वर्डप्रेस प्लगइन्स और थीम्स में ऑटोलेडिंग और नेमस्पेस: क्या यह काम कर सकता है?


70

क्या किसी ने प्लगइन या थीम के भीतर ऑटोलडिंग और / या PHP नामस्थान का उपयोग किया है ?

उनका उपयोग करने पर विचार? कोई हानि? नुकसान?

नोट: नामस्थान केवल PHP 5.3+ हैं। इस सवाल के लिए, मान लें कि आप जानते हैं कि आप उन सर्वरों से निपटेंगे जिनके बारे में आप जानते हैं कि PHP 5.3 या अधिक है।

जवाबों:


89

ठीक है, मेरे पास दो बड़ी परियोजनाएँ हैं जहाँ मैं सर्वर के नियंत्रण से लेकर नेमस्पेस तक और ऑटोलॉडिंग पर निर्भर हूं।

शुरुआत से। ऑटोलडिंग कमाल की है। आवश्यकता के बारे में चिंता न करना अपेक्षाकृत अच्छी बात है।

यहाँ एक लोडर है जिसका उपयोग मैं कुछ परियोजनाओं पर कर रहा हूँ। यह सुनिश्चित करने के लिए जाँच करता है कि कक्षा पहले नामस्थान में है, फिर नहीं तो घंटी। वहाँ से यह वर्ग खोजने के लिए कुछ स्ट्रिंग हेरफेर है।

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

कोई भी नाम-स्थान के बिना उपयोग के लिए इसे आसानी से अनुकूलित कर सकता है। यदि आप अपने प्लगइन / थीम की कक्षाओं को समान रूप से उपसर्ग मानते हैं, तो आप उस उपसर्ग के लिए परीक्षण कर सकते हैं। फिर निर्देशिका विभाजकों के लिए प्लेसहोल्डर के रूप में वर्ग नाम में अंडरस्कोर का उपयोग करें। यदि आप बहुत सारी कक्षाओं का उपयोग कर रहे हैं, तो आप कुछ प्रकार के क्लासमेट ऑटोलैडर का उपयोग करना चाहेंगे।

नाम और हुक

वर्डप्रेस का हुक सिस्टम 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__या 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 है, लेकिन यह मुझे बिट करता है, इसलिए यहां यह है।

आप उन चीजों को परिभाषित करना चाह सकते हैं जिनका आप अक्सर उपयोग करते हैं, जैसे आपके प्लगइन का मार्ग। डिफाइन स्टेटमेंट का उपयोग रूट नेमस्पेस में चीजों को डालता है जब तक कि आप स्पष्ट रूप से नाम स्थान को डिफेंस के पहले तर्क में पास नहीं करते हैं।

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

आप constPHP 5.3 प्लस के साथ फ़ाइल के रूट स्तर पर भी कीवर्ड का उपयोग कर सकते हैं । constss हमेशा वर्तमान नामस्थान में होते हैं, लेकिन कम लचीले होते हैं जो एक defineकॉल है।

<?php
namespace WPSE\SomeNameSpace;

// in the current namespace
const MY_CONST = 1;

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

कृपया किसी भी अन्य युक्तियों को जोड़ने के लिए स्वतंत्र महसूस करें!


16

यहां 2017 का जवाब है।

ऑटोलडिंग कमाल की है। नेमस्पेसिंग कमाल की है।

यद्यपि आप इसे स्वयं रोल कर सकते हैं, 2017 में यह आपके PHP आवश्यकताओं को संभालने के लिए शानदार और सर्वव्यापी संगीतकार का उपयोग करने के लिए सबसे अधिक समझ में आता है । संगीतकार PSR-0 और PSR-4 दोनों को ऑटोलिडिंग का समर्थन करता है , लेकिन 2014 के बाद से पूर्व को हटा दिया गया है, इसलिए PSR-4 का उपयोग करें। यह आपकी निर्देशिकाओं की जटिलता को कम करता है।

हम अपने प्रत्येक प्लगइन्स / थीम को अपने गिथब रिपॉजिटरी में रखते हैं, प्रत्येक अपनी 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फ़ाइल प्रदान करते हैं , तो संगीतकार यहां नाम-रिक्ति और ऑटोलॉडिंग को संभालता है।

{
    "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';

...

बोनस सुविधा

आवश्यकता नहीं है, लेकिन हम शुरू से ही संगीतकार का उपयोग करने के लिए बेडरॉक वर्डप्रेस बॉयलरप्लेट का उपयोग करते हैं। फिर हम कंपोज़र का उपयोग कर सकते हैं जो कि हमें अपने द्वारा लिखे गए प्लग इन सहित कम्पोज़र के माध्यम से आवश्यक प्लगइन्स को इकट्ठा करने के लिए चाहिए। इसके अतिरिक्त, 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: मैंने brevity के लिए बॉयलरप्लेट बेडरॉक फ़ाइल के कुछ बिट्स को काट दिया है।

नोट 3: यही कारण है कि typeपहली composer.jsonफ़ाइल में फ़ील्ड महत्वपूर्ण है। संगीतकार स्वचालित रूप से इसे web/app/pluginsनिर्देशिका में छोड़ देता है।


आपके उत्तर की सराहना, बहुत उपयोगी! लेकिन मैं "bootstrap.php" के बारे में उत्सुक हूं, जिसका आप उल्लेख कर रहे हैं। इसमें क्या शामिल है? :)
INT

1
बूटस्ट्रैप.php फ़ाइल का होना एक शैलीगत बात है जो मैं अपनी अधिकांश परियोजनाओं में, WP में या उससे बाहर करता हूं। मेरा बूटस्ट्रैपर आम तौर पर सेटिंग्स और पर्यावरण चर की जांच करता है; इसका मुख्य उद्देश्य यह सुनिश्चित करना है कि मेरे प्लगइन में हमेशा वही है जो उसे चलाने की आवश्यकता है, चाहे वह WP के भीतर से चलाया गया हो या स्टैंडअलोन PHP ऐप के रूप में।
खतरनाक

4

मैं ऑटोलोदिंग का उपयोग करता हूं (जैसा कि मेरे प्लगइन में कक्षाओं का भार है - आंशिक रूप से क्योंकि इसमें ट्विग शामिल है), कभी भी मेरे ध्यान में लाया गया मुद्दा नहीं था (प्लगइन स्थापित 20,000 बार)।

यदि आप आश्वस्त हैं कि आपको कभी भी php इंस्टालेशन का उपयोग करने की आवश्यकता नहीं होगी जो नामस्थानों का समर्थन नहीं करता है तो फिर से आप ठीक हैं (~ मौजूदा वर्डप्रेस ब्लॉगों के 70% नामस्थानों का समर्थन नहीं करते हैं)। ध्यान देने योग्य कुछ बातें:

मुझे याद है कि नाम स्थान नियमित रूप से php में संवेदनशील नहीं होते हैं, लेकिन जब iis पर fastcgi php का उपयोग कर रहे हैं - यह कुछ सिरदर्द का कारण बनता है यदि आप linux पर परीक्षण करते हैं और एक बदमाश लोअरकेस पत्र को स्पॉट नहीं करते हैं।

इसके अलावा, भले ही आपको यकीन हो कि आप वर्तमान में जो कोड विकसित कर रहे हैं, उसका उपयोग केवल> 5.3.0 पर ही किया जाएगा, आप ऐसी किसी भी कोड का पुन: उपयोग नहीं कर पाएंगे, जिनके पास वह लक्जरी नहीं है - यही मुख्य कारण है कि मैंने ऐसा क्यों नहीं किया है आंतरिक परियोजनाओं पर नाम स्थान का उपयोग किया। मैं ने पाया है कि नामस्थान वास्तव में उपयोगी नहीं होते कि बहुत जब उन पर निर्भरता को निकालना होने के संभावित सिर दर्द के साथ तुलना में।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.