Oke, saya punya dua proyek besar di mana saya sudah mengendalikan server cukup untuk namespace dan mengandalkan autoloading.
Pertama. Autoloading luar biasa. Tidak perlu khawatir tentang kebutuhan adalah hal yang relatif baik.
Inilah loader yang telah saya gunakan pada beberapa proyek. Cek untuk memastikan kelas berada di namespace saat ini terlebih dahulu, kemudian menebus jika tidak. Dari sana hanya beberapa manipulasi string untuk menemukan kelas.
<?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);
}
Orang dapat dengan mudah menyesuaikan ini untuk digunakan tanpa ruang nama. Anggap Anda awalan kelas plugin / tema Anda secara seragam, Anda bisa menguji awalan itu. Kemudian gunakan garis bawah pada nama kelas untuk sebagai placeholder untuk pemisah direktori. Jika Anda menggunakan banyak kelas, Anda mungkin ingin menggunakan semacam autoloader classmap.
Ruang nama dan Kait
Sistem kait WordPress bekerja dengan menggunakan call_user_func
(dan call_user_func_array
), yang menggunakan nama fungsi sebagai string dan memanggil mereka saat panggilan fungsi do_action
(dan selanjutnya call_user_func
) dibuat.
Dengan ruang nama, itu berarti Anda harus memberikan nama fungsi yang sepenuhnya memenuhi syarat yang menyertakan namespace ke dalam kait.
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', 'WPSE\\SomeNameSpace\\the_function');
function the_function()
{
return 'did stuff';
}
Mungkin akan lebih baik untuk menggunakan __NAMESPACE__
sihir konstan secara liberal jika Anda ingin melakukan ini.
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', __NAMESPACE__ . '\\the_function');
function the_function()
{
return 'did stuff';
}
Jika Anda selalu memasukkan kait ke dalam kelas, itu lebih mudah. Standar membuat instance kelas dan semua kait di konstruktor dengan $this
berfungsi dengan baik.
<?php
namespace WPSE\SomeNameSpace;
new Plugin;
class Plugin
{
function __construct()
{
add_action('plugins_loaded', array($this, 'loaded'));
}
function loaded()
{
// this works!
}
}
Jika Anda menggunakan metode statis seperti yang ingin saya lakukan, Anda harus memberikan nama kelas yang sepenuhnya memenuhi syarat sebagai argumen pertama array. Itu banyak pekerjaan, jadi Anda bisa menggunakan __CLASS__
konstanta sihir atau 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!
}
}
Menggunakan Kelas Inti
Resolusi classname PHP agak miring. Jika Anda akan menggunakan kelas inti WP ( WP_Widget
dalam contoh di bawah), Anda harus memberikan use
pernyataan.
use \WP_Widget;
class MyWidget extends WP_Widget
{
// ...
}
Atau Anda dapat menggunakan nama kelas yang sepenuhnya memenuhi syarat - pada dasarnya hanya awalan dengan backslash.
<?php
namespace WPSE\SomeNameSpace;
class MyWidget extends \WP_Widget
{
// ...
}
Mendefinisikan
Ini adalah PHP yang lebih umum, tetapi ini menggigit saya, jadi ini dia.
Anda mungkin ingin mendefinisikan hal-hal yang akan sering Anda gunakan, seperti jalur ke plugin Anda. Menggunakan pernyataan define menempatkan sesuatu di root namespace kecuali Anda secara eksplisit melewatkan namespace ke argumen pertama define.
<?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__));
Anda juga dapat menggunakan const
kata kunci pada level root file dengan PHP 5.3 plus. consts
s selalu ada dalam namespace saat ini, tetapi kurang fleksibel dibandingkan define
panggilan.
<?php
namespace WPSE\SomeNameSpace;
// in the current namespace
const MY_CONST = 1;
// this won't work!
const MY_PATH = plugin_dir_path(__FILE__);
Silahkan menambahkan tips lain yang mungkin Anda miliki!
Saya menggunakan autoloading (karena plugin saya memiliki banyak kelas - sebagian karena termasuk Twig), tidak pernah ada masalah yang menarik perhatian saya (plugin terpasang> 20.000 kali).
Jika Anda yakin bahwa Anda tidak akan pernah perlu menggunakan instalasi php yang tidak mendukung ruang nama maka sekali lagi Anda baik-baik saja (~ 70% dari blog wordpress saat ini tidak mendukung ruang nama). Beberapa hal yang perlu diperhatikan:
Saya sepertinya ingat bahwa ruang nama tidak peka huruf besar-kecil di php biasa tetapi ketika menggunakan fastcgi php di iis - ini menyebabkan beberapa sakit kepala jika Anda menguji di linux dan tidak melihat huruf kecil yang nakal.
Bahkan jika Anda yakin kode yang sedang Anda kembangkan hanya akan digunakan pada> 5.3.0 Anda tidak akan dapat menggunakan kembali kode apa pun dengan proyek yang tidak memiliki kemewahan itu - itulah alasan utama mengapa saya belum ruang nama yang digunakan pada proyek internal. Saya telah menemukan bahwa ruang nama benar-benar tidak menambahkan bahwa banyak bila dibandingkan dengan sakit kepala mungkin harus menghapus ketergantungan pada mereka.
sumber