Được rồi, tôi đã có hai dự án lớn, nơi tôi đã kiểm soát máy chủ đủ để không gian tên và dựa vào tự động tải.
Đầu tiên lên. Tự động tải là tuyệt vời. Không phải lo lắng về yêu cầu là một điều tương đối tốt.
Đây là một trình tải tôi đã sử dụng cho một vài dự án. Kiểm tra để chắc chắn rằng lớp nằm trong không gian tên hiện tại trước, sau đó bảo lãnh nếu không. Từ đó, chỉ cần một số thao tác chuỗi để tìm lớp.
<?php
spl_autoload_register(__NAMESPACE__ . '\\autoload');
function autoload($cls)
{
$cls = ltrim($cls, '\\');
if(strpos($cls, __NAMESPACE__) !== 0)
return;
$cls = str_replace(__NAMESPACE__, '', $cls);
$path = PLUGIN_PATH_PATH . 'inc' .
str_replace('\\', DIRECTORY_SEPARATOR, $cls) . '.php';
require_once($path);
}
Người ta có thể dễ dàng điều chỉnh nó để sử dụng mà không cần không gian tên. Giả sử bạn có tiền tố các lớp / chủ đề của plugin một cách thống nhất, bạn chỉ có thể kiểm tra tiền tố đó. Sau đó sử dụng dấu gạch dưới trong tên lớp để làm chỗ dành cho các dấu tách thư mục. Nếu bạn đang sử dụng nhiều lớp, có thể bạn sẽ muốn sử dụng một số loại trình tải tự động lớp.
Không gian tên và móc
Hệ thống hook của WordPress hoạt động bằng cách sử dụng call_user_func
(và call_user_func_array
), lấy tên hàm làm chuỗi và gọi chúng khi cuộc gọi hàm do_action
(và sau đó call_user_func
) được thực hiện.
Với các không gian tên, điều đó có nghĩa là bạn sẽ cần chuyển các tên hàm đủ điều kiện bao gồm không gian tên thành các móc.
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', 'WPSE\\SomeNameSpace\\the_function');
function the_function()
{
return 'did stuff';
}
Có lẽ sẽ tốt hơn nếu sử dụng __NAMESPACE__
phép thuật tự do liên tục nếu bạn muốn làm điều này.
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', __NAMESPACE__ . '\\the_function');
function the_function()
{
return 'did stuff';
}
Nếu bạn luôn đặt móc của mình vào các lớp học, điều đó sẽ dễ dàng hơn. Ví dụ tạo tiêu chuẩn của một lớp và tất cả các hook trong hàm tạo có $this
hoạt động tốt.
<?php
namespace WPSE\SomeNameSpace;
new Plugin;
class Plugin
{
function __construct()
{
add_action('plugins_loaded', array($this, 'loaded'));
}
function loaded()
{
// this works!
}
}
Nếu bạn sử dụng các phương thức tĩnh như tôi muốn làm, bạn sẽ cần phải chuyển tên lớp đủ điều kiện làm đối số đầu tiên của mảng. Đó là rất nhiều công việc, vì vậy bạn chỉ cần sử dụng __CLASS__
hằng số ma thuật hoặc get_class
.
<?php
namespace WPSE\SomeNameSpace;
Plugin::init();
class Plugin
{
public static function init()
{
add_action('plugins_loaded', array(__CLASS__, 'loaded'));
// OR: add_action('plugins_loaded', array(get_class(), 'loaded'));
}
public static function loaded()
{
// this works!
}
}
Sử dụng các lớp lõi
Độ phân giải tên lớp của PHP là một chút khó khăn. Nếu bạn sẽ sử dụng các lớp WP cốt lõi ( WP_Widget
trong ví dụ bên dưới), bạn phải cung cấp các use
câu lệnh.
use \WP_Widget;
class MyWidget extends WP_Widget
{
// ...
}
Hoặc bạn có thể sử dụng tên lớp đủ điều kiện - về cơ bản chỉ cần thêm tiền tố vào dấu gạch chéo ngược.
<?php
namespace WPSE\SomeNameSpace;
class MyWidget extends \WP_Widget
{
// ...
}
Xác định
Đây là PHP tổng quát hơn, nhưng nó cắn tôi, vì vậy nó ở đây.
Bạn có thể muốn xác định những thứ bạn sẽ sử dụng thường xuyên, như đường dẫn đến plugin của bạn. Sử dụng câu lệnh xác định sẽ đặt mọi thứ trong không gian tên gốc trừ khi bạn rõ ràng chuyển không gian tên vào đối số đầu tiên của định nghĩa.
<?php
namespace WPSE\SomeNameSpace;
// root namespace
define('WPSE_63668_PATH', plugin_dir_path(__FILE__));
// in the current namespace
define(__NAMESPACE__ . '\\PATH', plugin_dir_path(__FILE__));
Bạn cũng có thể sử dụng const
từ khóa ở cấp độ gốc của tệp với PHP 5.3 plus. consts
s luôn ở trong không gian tên hiện tại, nhưng kém linh hoạt hơn một define
cuộc gọi.
<?php
namespace WPSE\SomeNameSpace;
// in the current namespace
const MY_CONST = 1;
// this won't work!
const MY_PATH = plugin_dir_path(__FILE__);
Xin vui lòng thêm bất kỳ lời khuyên nào khác mà bạn có thể có!