WordPress 플러그인 및 테마의 자동로드 및 네임 스페이스 : 작동합니까?


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이지만, 저를 깨 물었습니다.

플러그인 경로와 같이 자주 사용할 항목을 정의 할 수 있습니다. 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__));

constPHP 5.3 plus와 함께 파일의 루트 수준에서 키워드 on을 사용할 수도 있습니다 . 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 년에는 웅장하고 편재적인 Composer 를 사용하여 PHP 요구 사항을 처리 하는 것이 가장 합리적 입니다. Composer는 PSR-0PSR-4 자동 로딩을 모두 지원 하지만 전자는 2014 년부터 더 이상 사용되지 않으므로 PSR-4를 사용하십시오. 디렉토리의 복잡성을 줄입니다.

각 플러그인 / 테마는 자체 composer.json파일 및 composer.lock파일이 있는 자체 Github 리포지토리에 보관 합니다.

플러그인에 사용하는 디렉토리 구조는 다음과 같습니다. (우리는 실제로라는 플러그인을 가지고 있지 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';

...

보너스 기능

필수는 아니지만 Bedrock Wordpress 상용구를 사용하여 처음부터 Composer를 사용합니다. 그런 다음 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디렉토리에 놓습니다 .


도움을 주셔서 감사합니다. 하지만 당신이 말하는 "bootstrap.php"에 대해 궁금합니다. 무엇이 포함되어 있습니까? :)
INT

1
bootstrap.php 파일을 갖는 것은 WP의 안팎에서 대부분의 프로젝트에서 수행하는 문체입니다. 내 부트 스트 래퍼는 일반적으로 설정과 환경 변수를 확인합니다. 그것의 주요 목적은 플러그인이 WP 내에서 실행되었는지 또는 독립형 PHP 앱으로 실행되는지에 관계없이 항상 플러그인이 실행 해야하는 것을 갖도록하는 것입니다.
haz

4

자동로드를 사용합니다 (플러그인에는 클래스가 많기 때문에 부분적으로 Twig가 포함되어 있음). 내 문제가 발생하지 않았습니다 (플러그인 설치> 20,000 회).

네임 스페이스를 지원하지 않는 PHP 설치를 사용할 필요가 없다고 확신한다면 다시 잘해도됩니다 (현재 워드 프레스 블로그의 ~ 70 %는 네임 스페이스를 지원하지 않습니다). 몇 가지 참고할 사항 :

네임 스페이스는 일반 PHP에서 대소 문자를 구분하지 않지만 iis에서 fastcgi php를 사용할 때입니다. 리눅스에서 테스트하고 악성 소문자를 발견하지 않으면 두통이 발생합니다.

또한 현재 개발중인 코드가 5.3.0 이상에서만 사용된다고 확신하더라도 사치가없는 프로젝트에서는 코드를 재사용 할 수 없습니다. 이것이 내가하지 않은 주된 이유입니다 내부 프로젝트에서 네임 스페이스를 사용했습니다. 네임 스페이스 는 의존성을 제거 해야하는 두통과 비교할 때 실제로 그렇게 많이 추가하지 않는다는 것을 알았습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.