WordPress Eklentilerinde ve Temalarında Otomatik Yükleme ve Ad Alanları: Çalışabilir mi?


70

Bir eklenti veya tema içerisinde otomatik yükleme ve / veya PHP ad alanları kullanan var mı?

Onları kullanma hakkında düşünceler? Herhangi bir zarar? Tuzaklar?

Not: İsim alanları sadece PHP 5.3+. Bu soru için, PHP 5.3 veya üstü olan tanıdığınız sunucularla ilgileneceğinizi bildiğinizi varsayalım.

Yanıtlar:


89

Tamam, sunucunun ad alanını kontrol etmeye ve otomatik yüklemeye güvenmeye yetecek kadar kontrol ettiği iki büyük projem vardı.

İlk. Otomatik yükleme harika. Gerektiği için endişelenmemek nispeten iyi bir şey.

İşte birkaç projede kullandığım bir yükleyici. Sınıfın önce geçerli ad alanında olduğundan emin olmak için kontrol eder, sonra yapmazsa kefalet öder. Oradan sadece sınıfı bulmak için bazı string manipülasyon var.

<?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);
}

Kişi bunu ad alanları olmadan kullanmak için kolayca uyarlayabilir. Eklentinizin / temalarının sınıflarını eşit olarak öneklediğinizi varsayarsak, sadece bu öneki test edebilirsiniz. Sonra sınıf adındaki alt çizgi dizini ayırıcılar için yer tutucu olarak kullanın. Çok fazla sınıf kullanıyorsanız, bir tür sınıf haritası otomatik yükleyici kullanmak isteyebilirsiniz.

İsim Alanları ve Kancalar

WordPress 'hooks sistemi , fonksiyon isimlerini dizge olarak alan ve (ve daha sonra ) işlev çağrısı yapıldığında onları çağıran call_user_func(ve call_user_func_array) kullanarak çalışır .do_actioncall_user_func

Ad alanlarıyla, bu, ad alanını içeren tam işlevli işlev adlarını kancalara geçirmeniz gerektiği anlamına gelir.

<?php
namespace WPSE\SomeNameSpace;

add_filter('some_filter', 'WPSE\\SomeNameSpace\\the_function');
function the_function()
{
   return 'did stuff';
}

Bunu yapmak __NAMESPACE__istersen , büyüyü liberal bir şekilde kullanmak, muhtemelen daha iyi olur .

<?php
namespace WPSE\SomeNameSpace;

add_filter('some_filter', __NAMESPACE__ . '\\the_function');
function the_function()
{
   return 'did stuff';
}

Kancanızı daima sınıfa koyarsanız, daha kolaydır. Standart bir sınıf örneği yaratır ve yapıcıdaki tüm kancalar $thisiyi çalışır.

<?php
namespace WPSE\SomeNameSpace;

new Plugin;

class Plugin
{
    function __construct()
    {
        add_action('plugins_loaded', array($this, 'loaded'));
    }

    function loaded()
    {
        // this works!
    }
}

Yapmak istediğim gibi statik yöntemler kullanıyorsanız, dizinin ilk argümanı olarak tam sınıf adını girmeniz gerekir. Bu çok iş, yani sihir __CLASS__sabitini kullanabilirsin ya da 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!
    }
}

Çekirdek Sınıfları Kullanma

PHP'nin sınıf adı çözünürlüğü biraz riskli. Çekirdek WP sınıflarını kullanacaksanız ( WP_Widgetaşağıdaki örnekte) useifadeler sağlamalısınız .

use \WP_Widget;

class MyWidget extends WP_Widget
{
   // ...
}

Veya tam nitelikli sınıf adını kullanabilirsiniz - temelde sadece ters eğik çizgi ile önek.

<?php
namespace WPSE\SomeNameSpace;

class MyWidget extends \WP_Widget
{
   // ...
}

tanımlar

Bu daha genel PHP, ama beni ısırdı, işte burada.

Eklentinizin yolu gibi sık kullanacağınız şeyleri tanımlamak isteyebilirsiniz. Tanım deyimini kullanmak, ad alanını tanımlamanın ilk argümanına açıkça iletmediğiniz sürece, şeyleri kök ad alanına koyar.

<?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__));

constAnahtar kelimeyi, PHP 5.3 plus ile bir dosyanın kök düzeyinde de kullanabilirsiniz . constss her zaman geçerli ad alanındadır, ancak definearamadan daha az esnektir .

<?php
namespace WPSE\SomeNameSpace;

// in the current namespace
const MY_CONST = 1;

// this won't work!
const MY_PATH = plugin_dir_path(__FILE__);

Lütfen sahip olabileceğiniz diğer ipuçlarını eklemekten çekinmeyin!


16

İşte bir 2017 cevabı.

Otomatik yükleme harika. İsim alanı harika.

Kendinizi yuvarlayabilseniz de, 2017'de PHP gereksinimlerinizi karşılamak için görkemli ve her yerde bulunan Besteci kullanmak en mantıklı olanıdır . Besteci destekler PSR-0 ve PSR-4 Özdevinimli, fakat eski 2014 yılından beri kullanımdan kaldırıldı, bu yüzden PSR-4 kullanın. Dizinlerinizin karmaşıklığını azaltır.

Biz kendi kendi Github depoda bizim eklentileri / temaları her biri her tutmak composer.jsondosya ve composer.lockdosyada.

İşte eklentilerimiz için kullandığımız dizin yapısı. (Gerçekten denilen bir eklentimiz yok awesome-plugin, ama yapmalıyız.)

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/*

Uygun bir composer.jsondosya sağlarsanız , Besteci burada ad boşluğunu ve otomatik yüklemeyi işler.

{
    "name": "awesome-company/awesome-plugin",
    "description": "Wordpress plugin for AwesomeCompany website, providing awesome functionality.",
    "type": "wordpress-plugin",
    "autoload": {
        "psr-4": {
            "AwesomeCompany\\Plugins\\AwesomePlugin\\": "src"
        }
    }
}

Çalıştırdığınızda composer install, vendordizinde ve vendor/autoload.phpad boşluklu dosyalarınızı src/ve ihtiyaç duyabileceğiniz diğer kitaplıkları otomatik olarak yükleyecek dosyayı oluşturur .

Sonra ana eklenti dosyanızın en üstünde (bizim için olan awesome-plugin.php), eklenti meta verilerinizden sonra, yapmanız gereken tek şey:

// Composer autoloading.
require_once __DIR__ . '/vendor/autoload.php';

...

Bonus Özelliği

Zorunlu değil, ama en başından beri Composer'ı kullanmak için Bedrock Wordpress kazanını kullanıyoruz. Daha sonra, yukarıda yazdığınız kendi eklentiniz de dahil olmak üzere, Composer aracılığıyla ihtiyaç duyduğumuz eklentileri bir araya getirmek için Composer'ı kullanabiliriz. Ayrıca, sayesinde WPackagist , sen Wordpress.org başka herhangi eklentisi gerektirebilir (örnek bakınız cool-themeve cool-pluginaşağıda).

{
  "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"
    ]
  }
}

Not 1: Yorumlar JSON'da yasal değildir, ancak daha fazla netlik için yukarıdaki dosyaya açıklama ekledim.

Not 2: Kısıtlılık Bedrock dosyasının bazı parçalarını kısaltmak için parçaladım.

Not 3: Bu nedenle typeilk composer.jsondosyadaki alan önemlidir. Besteci otomatik olarak web/app/pluginsdizine bırakır .


Cevabınızı takdir edin, çok faydalı! Ama bahsettiğiniz "bootstrap.php" hakkında merak ediyorum. Ne içeriyor? :)
INT

1
Bir bootstrap.php dosyasına sahip olmak, projelerimin çoğunda, WP'nin içinde veya dışında yaptığım stilistik bir şey. Bootstrapper'ım normalde sadece ayarları ve ortam değişkenlerini kontrol eder; Asıl amacı, eklentimin WP'den veya bağımsız bir PHP uygulaması olarak çalıştırılıp çalıştırılmadığına bakılmaksızın her zaman çalışması için gerekenlere sahip olmasını sağlamaktır.
haz

4

Otomatik yükleme kullanıyorum (eklentim bir sürü sınıfa sahip olduğundan - kısmen Twig içerdiğinden), hiçbir zaman dikkatimi çekmedi (eklenti> 20.000 kez yüklendi).

Asla ad alanlarını desteklemeyen bir php kurulumu kullanmak zorunda kalmayacağınıza eminseniz, o zaman yine iyisiniz (mevcut wordpress bloglarının ~% 70'i ad alanlarını desteklemiyor). Unutulmaması gereken birkaç şey:

Ad alanlarının normal php'lerde büyük / küçük harf duyarlı olmadıklarını, ancak iis'de fastcgi php kullanırken olduklarını hatırlıyor gibiyim - eğer linux üzerinde test yaparsanız ve küçük bir harf görmüyorsanız bu baş ağrısına neden olur.

Ayrıca, şu anda geliştirmekte olduğunuz kodun yalnızca> 5.3.0’da kullanılacağından emin olsanız bile, bu lüksü olmayan projelerle herhangi bir kodu tekrar kullanamayacaksınız - bu benim olmamamın temel nedeni. iç projelerde kullanılan ad alanları. Ben ad gerçekten katmayan bulduk o onlara bağımlılığını kaldırmak zorunda olası baş ağrısı ile karşılaştırıldığında çok.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.