Eklentimde spl_autoload_register () kullanmalı mıyım?


11

Eklentimde spl_autoload_register kullandığımda:

    Fatal error: Uncaught exception 'LogicException' with message
   'Class wp_atom_server could not be loaded'

    wp-includes\pluggable-deprecated.php on line 182

Biraz okuma yaptım ve çeşitli düzeltmeler buldum. SO üzerinde bir WordPress ile spl_autoload_register kullanmamayı söyledi.

Bu doğru mu?

Hata için bir "düzeltme" bulabileceğime eminim, ancak her WP sürümü ile bunu yapmak istediğimden emin değilim.

Otomatik yükleme işlevini kullanmazsam, sınıflarımı nasıl yüklemeliyim? İşte şimdi kırılan şey:

spl_autoload_extensions(".php");
spl_autoload_register();

use MyPluginClasses\Student as MS;

$student = new MS\Student();

echo $student->sayHello();

Öğrenci:

<?PHP
namespace MyPluginClasses\Student
{
    class Student{
        public function __Construct(){
            echo "Hello Johnny";
        }
        public function sayHello(){
            echo "Hello Johnny's Method";

        }

    }
}

Bu tasarım WordPress dışında iyi çalışıyor.


4
Cevabımı güncelledim . Bunu doğru yaparsanız - geri arama işleviyle - spl_autoload_register()olumsuz yan etkiler olmadan kullanabilirsiniz .
fuxia

1
@toscho Kodunuz hala WP'de otomatik yükleme yapmanın en iyi yolu mu?
johnny

Hayır öyle değil. En hızlı yol glob()dizine bir kez, sonra sınıfları gerektiğinde teslim etmektir spl_autoload_register().
fuxia

1
Daha sonra, Çok Dilde Basın'dan mevcut (henüz yayınlanmamış) çözümümüzü gösteren bir cevap yazacağım.
fuxia

Yanıtlar:


1

WP eklentisindeki sınıfları otomatik olarak yüklemenin iyi ya da kötü bir uygulama olup olmadığından gerçekten emin değilim. Benim için kullanmanın hiçbir yan etkisi görmüyorum spl_autoload_register(test edilmemiş performans)

Sorunuzu cevaplamak için, herhangi bir sorun olmadan tek bir dizinden sınıfları otomatik olarak yüklemek için kullanacağım yaklaşan eklentimden bir sınıf paylaşmak istiyorum ve şimdiye kadar benim için iyi.

/**
 * Annframe Class Autoloader.
 *
 * @package Annframe
 * @since 0.1.0
 */
class Annframe_Autoloader {
    /**
     * Singleton.
     *
     * @since 0.1.0
     * @var Annframe_Autoloader - Single instance.
     */
    private static $_instance = null;

    /**
     * Private Construct.
     *
     * @package Annframe
     * @since 0.1.0
     */
    private function __construct() {
        spl_autoload_register( array( $this, 'load' ) );
    }

    /**
     * Singleton method.
     *
     * @package Annframe
     * @since 0.1.0
     */
    public static function _instance() {
        if ( ! self::$_instance ) {
            self::$_instance = new Annframe_Autoloader();
        }
        return self::$_instance;
    }

    /**
     * Class Loader.
     *
     * @package Annframe
     * @since 0.1.0
     *
     * @param string $class_name - Class name to load.
     * @return null - Do not return anything.
     */
    public function load( $class_name ) {
        $file = str_replace( '_', '-', strtolower( $class_name ) );
        $file = 'class-' . $file;
        if ( is_readable( trailingslashit( YOUR_PLUGIN_PATH. '/classes-dir' ) . $file . '.php' ) ) {
            include_once trailingslashit( YOUR_PLUGIN_PATH. '/classes-dir' ) . $file . '.php';
        }
        return;
    }
}

Annframe_Autoloader::_instance();

Gördüğünüz gibi parçalar halinde bu basit sınıf kırmak için ben Singleton desen kullanıyorum. Constructorözel ve instance()& $_instancedesen aittir. Yapıcı spl_autoload_registerişlevi vardır.

spl_autoload_register( array( $this, 'load' ) );

loadkendi kendini sınıftan çağıran yöntemdir. Bu yöntemin ilk iki satırı şöyledir:

$file = str_replace( '_', '-', strtolower( $class_name ) );
$file = 'class-' . $file;

ki bu oldukça düzdür. WPCS'yi izlerseniz , word sınıfı ve ardından sınıf adıyla ön eklenmiş bir sınıf adlandırma kuralını izlemenizi önerir . Tabii ki herhangi bir alt çizgi (_), (-) tire ile değiştirilir.

böylece sınıfın bir dosya adı WPSE_Postolurduclass-wpse-post.php

Alt kasa sınıf adlarını, alt çizgileri tire işaretleri ile değiştirmek strtolowerve kullanmak str_replaceiçin kullanın. böylece WPSE_Postşimdi olur wpse-post. son olarak bir class-sonraki satıra bir önek ekler .

is_readableile değiştirilebilir koşullu deyimde kullanıyorum file_exists. varsayalım YOUR_PLUGIN_PATHeklentinin temel yolu ve classes-dirotomatik yükleme gerektiren tüm sınıfları tutan ana eklenti dir altında.

include_once çağrı sırasında gerçek dosyayı yüklemek için kullanılır.

Kullanımı:

eklentinizin temel dosyasına yukarıdaki otomatik yükleyici sınıfını eklemeniz yeterlidir

/**
 * Class autoloader.
 */
if ( ! class_exists( 'Annframe_Autoloader' ) ) {
    include_once YOUR_PLUGIN_PATH/class-annframe-autoloader.php';
}

ve talep üzerine sınıflarınızı arayın.

new XYX_Class();
Another_Class::instance(); // etc

Not: Çözümümde ad alanı yöntemini kullanmıyorum, bu yüzden ihtiyaçlarınıza göre uygun olabilir veya olmayabilir, ancak en azından birinin dinamik olarak sınıfları yükleme avantajlarından yararlanmasını umuyoruz.


-1
    function MyPluginClasses_autoloader( $class_name ) {
  if ( false !== strpos( $class_name, 'MyPluginClasses' ) ) {
    $parts = explode('\\', $class_name);
    require_once RoothPath . DIRECTORY_SEPARATOR .'lib'.DIRECTORY_SEPARATOR.end($parts) . '.php';
  }
}
spl_autoload_register( 'MyPluginClasses_autoloader' );
use MyPluginClasses\Student as MS;
$student = new MS\Student();
echo $student->sayHello();

2
Kod gönderme iyi olsa da, bunun soruyu nasıl ve neden cevapladığını açıklamalısınız.
Laxmana

1
Eklentiniz sistemdeki tek eklenti olmadığından, sınıfları ilk önce sizin olduklarınızı doğrulamadan yükleyen kod, başka bir eklentide bildirilen bir sınıf için yanlış dosyayı yüklemeye çalışarak er ya da geç sorun yaratacaktır.
Mark Kaplun
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.