回答:
さて、名前空間とオートロードに依存するのに十分なほどサーバーを制御している2つの大きなプロジェクトがありました。
最初に。オートロードは素晴らしいです。requireを心配しないことは比較的良いことです。
これが私がいくつかのプロジェクトで使っているローダーです。最初にクラスが現在のネームスペースにあることを確認し、そうでない場合はベイルします。そこから、クラスを見つけるための単なる文字列操作です。
<?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);
}
名前空間なしで使用するためにこれを簡単に適合させることができます。プラグイン/テーマのクラスに均一にプレフィックスを付けると仮定すると、そのプレフィックスをテストできます。次に、クラス名にアンダースコアを使用して、ディレクトリ区切りのプレースホルダーとして使用します。多数のクラスを使用している場合は、何らかのクラスマップオートローダーを使用することをお勧めします。
WordPressのフックシステムは、call_user_func
(およびcall_user_func_array
)を使用して機能します。これは、関数名を文字列として受け取りdo_action
、call_user_func
関数呼び出しが行われたときに呼び出します。
名前空間を使用すると、名前空間を含む完全修飾関数名をフックに渡す必要があります。
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', 'WPSE\\SomeNameSpace\\the_function');
function the_function()
{
return 'did stuff';
}
これを行うには、おそらく__NAMESPACE__
マジック定数をリベラルに使用することをお勧めします。
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', __NAMESPACE__ . '\\the_function');
function the_function()
{
return 'did stuff';
}
フックを常にクラスに入れると、簡単になります。標準のクラスのインスタンスおよびコンストラクター内のすべてのフックは、$this
正常に機能します。
<?php
namespace WPSE\SomeNameSpace;
new Plugin;
class Plugin
{
function __construct()
{
add_action('plugins_loaded', array($this, 'loaded'));
}
function loaded()
{
// this works!
}
}
私がやりたいような静的メソッドを使用する場合、完全修飾クラス名を配列の最初の引数として渡す必要があります。これは大変な作業なので、魔法の__CLASS__
定数orを使用するだけ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!
}
}
PHPのクラス名解決は少し不安定です。コアWPクラスを使用する場合(WP_Widget
以下の例)、use
ステートメントを提供する必要があります。
use \WP_Widget;
class MyWidget extends WP_Widget
{
// ...
}
または、完全修飾クラス名を使用することもできます。基本的には、バックスラッシュを前に付けるだけです。
<?php
namespace WPSE\SomeNameSpace;
class MyWidget extends \WP_Widget
{
// ...
}
これはより一般的なPHPですが、私には噛み付きますので、ここにあります。
プラグインへのパスなど、頻繁に使用するものを定義することもできます。defineステートメントを使用すると、名前空間を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__));
const
PHP 5.3プラスのファイルのルートレベルでキーワードonを使用することもできます。 consts
sは常に現在のネームスペースにありますが、define
呼び出しほど柔軟ではありません。
<?php
namespace WPSE\SomeNameSpace;
// in the current namespace
const MY_CONST = 1;
// this won't work!
const MY_PATH = plugin_dir_path(__FILE__);
あなたが持っているかもしれない他のヒントを自由に追加してください!
これが2017年の答えです。
オートロードは素晴らしいです。名前空間は素晴らしいです。
自分でロールバックすることもできますが、2017年には、素晴らしく遍在するComposerを使用してPHPの要件を処理することが最も理にかなっています。ComposerはPSR-0とPSR-4の両方の自動ロードをサポートしていますが、前者は2014年以降廃止されているため、PSR-4を使用してください。ディレクトリの複雑さを軽減します。
プラグイン/テーマはそれぞれ独自のGithubリポジトリに保持され、それぞれに独自のcomposer.json
ファイルとcomposer.lock
ファイルがあります。
プラグインに使用するディレクトリ構造は次のとおりです。(というプラグインは実際にはありませんが、awesome-plugin
必要です。)
plugins/awesome-plugin/bootstrap.php
plugins/awesome-plugin/composer.json
plugins/awesome-plugin/composer.lock
plugins/awesome-plugin/awesome-plugin.php
plugins/awesome-plugin/src/*
plugins/awesome-plugin/vendor/autoload.php
plugins/awesome-plugin/vendor/*
適切なcomposer.json
ファイルを提供すると、Composerはここで名前の間隔と自動読み込みを処理します。
{
"name": "awesome-company/awesome-plugin",
"description": "Wordpress plugin for AwesomeCompany website, providing awesome functionality.",
"type": "wordpress-plugin",
"autoload": {
"psr-4": {
"AwesomeCompany\\Plugins\\AwesomePlugin\\": "src"
}
}
}
を実行composer install
すると、vendor
ディレクトリとvendor/autoload.php
ファイルが作成されます。これらのファイルは、にあるすべての名前空間ファイルとsrc/
、必要な他のライブラリを自動ロードします。
次に、メインプラグインファイル(これはawesome-plugin.php
)の上部で、プラグインメタデータの後に、次のものが必要です。
// Composer autoloading.
require_once __DIR__ . '/vendor/autoload.php';
...
必ずしも必要ではありませんが、最初からComposer を使用するには、Bedrock Wordpressボイラープレートを使用します。その後、Composerを使用して、Composerを介して必要なプラグインをアセンブルできます。これには、上記で作成した独自のプラグインも含まれます。また、おかげWPackagistは、あなたがWordpress.orgから、他のプラグインを必要とすることができます(例を参照cool-theme
してcool-plugin
以下に)。
{
"name": "awesome-company/awesome-website",
"type": "project",
"license": "proprietary",
"description": "WordPress boilerplate with modern development tools, easier configuration, and an improved folder structure",
"config": {
"preferred-install": "dist"
},
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org"
},
{ // Tells Composer to look for our proprietary Awesome Plugin here.
"url": "https://github.com/awesome-company/awesome-plugin.git",
"type": "git"
}
],
"require": {
"php": ">=5.5",
"awesome-company/awesome-plugin": "dev-production", // Our plugin!
"wpackagist-plugin/cool-plugin": "dev-trunk", // Someone else' plugin
"wpackagist-theme/cool-theme": "dev-trunk", // Someone else' theme
"composer/installers": "~1.2.0", // Bedrock default
"vlucas/phpdotenv": "^2.0.1", // Bedrock default
"johnpbloch/wordpress": "4.7.5", // Bedrock default
"oscarotero/env": "^1.0", // Bedrock default
"roots/wp-password-bcrypt": "1.0.0" // Bedrock default
},
"extra": {
// This is the magic that drops packages with the correct TYPE in the correct location.
"installer-paths": {
"web/app/mu-plugins/{$name}/": ["type:wordpress-muplugin"],
"web/app/plugins/{$name}/": ["type:wordpress-plugin"],
"web/app/themes/{$name}/": ["type:wordpress-theme"]
},
"wordpress-install-dir": "web/wp"
},
"scripts": {
"test": [
"vendor/bin/phpcs"
]
}
}
注1:JSONではコメントは合法ではありませんが、明確にするために上記のファイルに注釈を付けました。
注2:簡潔にするために、定型的なBedrockファイルの一部を切り取りました。
注3:これがtype
、最初のcomposer.json
ファイルのフィールドが重要な理由です。Composerは自動的にweb/app/plugins
ディレクトリにドロップします。
プラグインにはクラスの負荷があるため(一部にはTwigが含まれているため)オートロードを使用しますが、問題に気付かれたことはありません(プラグインのインストール> 20,000回)。
名前空間をサポートしないphpインストールを使用する必要がないと確信している場合は、問題ありません(現在のワードプレスブログの〜70%は名前空間をサポートしていません)。注意すべきいくつかの点:
名前空間は通常のphpでは大文字と小文字を区別しませんが、iisでfastcgi phpを使用している場合は覚えているようです。
また、現在開発中のコードが5.3.0以上でのみ使用されると確信している場合でも、その贅沢を持たないプロジェクトでコードを再利用することはできません。内部プロジェクトで使用されている名前空間。名前空間は、依存関係を削除しなければならないという頭痛の種と比較すると、それほど多くは追加されないことがわかりました。