Spl_autoload_register zaten kullanıldığında neden unserialize_callback_func gereklidir?

2 Cevap php

2 Cevap

I dkimlik some tests, and here are the notes I took (hope it'll be understandable ^^ ;; and that I dkimlikn't get too lost in my own thought ^^ )
Note : I've done my tests on PHP 5.3.2-dev, in case it matters.


First of all, let's define a temp-2.php file, that's going to contain only this :

<?php

class a {

}

biz nesneleştirmek çalışıyor olacak nesnesine karşılık gelen sınıfın tanımını yani.

temp-2.php böylece sınıf 'tanımı bilinen katmak gerekir - Ve ben yayınlayacağız kodu diğer tüm bölümleri denir temp.php bir dosyada yer alacaktır.


İlk deneyin: Biz sınıf tanımlanan kalmadan, dize nesneleştirmek try a:

$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';

function callback_spl($className)  {
    var_dump(__FUNCTION__ . ' : ' . $className);
}

spl_autoload_register('callback_spl');
$data = unserialize($serialized_object);
var_dump($data);

Çıkış olarak, biz bu olsun:

string 'callback_spl : a' (length=16)

object(__PHP_Incomplete_Class)[1]
  public '__PHP_Incomplete_Class_Name' => string 'a' (length=1)
    public 'value' => string '100' (length=3)

Bu da şu anlama gelir:

  • The autoloading function callback_spl has been called
    • spl_autoload_register tarafından tescil bile
    • Ama bir şey özdevinimli değil
  • Sınıf olarak özdevinimli değil Ve, biz __PHP_Incomplete_Class örnek bir nesneyi almak


Now, let's try using spl_autoload_register to register an autoloading function that actually autoloads the class' definition :

$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';

function callback_spl($className)  {
    var_dump(__FUNCTION__ . ' : ' . $className);
    require dirname(__FILE__) . '/temp-2.php';
}

spl_autoload_register('callback_spl');
$data = unserialize($serialized_object);
var_dump($data);

Ve biz bu çıktıya olsun:

string 'callback_spl : a' (length=16)

object(a)[1]
  public 'value' => string '100' (length=3)

Anlamı:

  • The autoloading function registered by spl_autoload_register has been called
    • Ve bu sefer, o sınıfın tanımını içeren dosyayı gerek yoktu
  • The un-serialization has been successful
    • yani biz __PHP_Incomplete_Class Artık bir örneğini alamadım
    • biz aslında a bir örneğini almak

spl_autoload_register kullanıldığı zaman So, here, I would say that unserialize_callback_func gerekli değildir.

I think, here, that I've kind of answered the question ? But I'll post a couple of other tests, just for fun ^^



Now, what if we try using unserialize_callback_func, and not using spl_autoload_register ?
The code will look like his, I suppose :

$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';

ini_set('unserialize_callback_func', 'callback_no_spl');

function callback_no_spl($className)  {
    var_dump(__FUNCTION__ . ' : ' . $className);
    require dirname(__FILE__) . '/temp-2.php';
}

$data = unserialize($serialized_object);
var_dump($data);

Ve, çıkış olarak, biz olsun:

string 'callback_no_spl : a' (length=19)

object(a)[1]
  public 'value' => string '100' (length=3)

Yani, her şey Tamam çalışır:

  • The callback_no_spl callback function registered via unserialize_callback_func is called
    • Bu sınıfın tanımını yükler
  • And the data is unserialized properly
    • yani biz a bir örneğini almak


Going a bit farther, let's try what we can get when both :

  • unserialize_callback_func ile callback_no_spl adında bir özdevinimli_yükle işlevi, Ayar
  • Ve ile callback_spl adlı başka bir özdevinimli_yükle fonksiyonu, ayar spl_autoload_register

Kod aşağıdaki gibi görünecektir:

$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';

ini_set('unserialize_callback_func', 'callback_no_spl');
function callback_no_spl($className)  {
    var_dump(__FUNCTION__ . ' : ' . $className);
    require dirname(__FILE__) . '/temp-2.php';
}

spl_autoload_register('callback_spl');
function callback_spl($className)  {
    var_dump(__FUNCTION__ . ' : ' . $className);
    require dirname(__FILE__) . '/temp-2.php';
}

$data = unserialize($serialized_object);
var_dump($data);

Ve çıkış elde ederiz:

string 'callback_spl : a' (length=16)

object(a)[1]
  public 'value' => string '100' (length=3)

Anlamı:

  • spl_autoload_register anılmıştır kayıtlı olan, sadece autoloading fonksiyonu
  • It dkimlik load the file that contains the class' definition
  • Ve veriler düzgün dizgilenmemiş olmuştur.


Now, just for fun, what if we try changing the order in which we set the autoloaders ?
i.e. use this portion of code :

$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';

spl_autoload_register('callback_spl');
function callback_spl($className)  {
    var_dump(__FUNCTION__ . ' : ' . $className);
    require dirname(__FILE__) . '/temp-2.php';
}

ini_set('unserialize_callback_func', 'callback_no_spl');
function callback_no_spl($className)  {
    var_dump(__FUNCTION__ . ' : ' . $className);
    require dirname(__FILE__) . '/temp-2.php';
}

$data = unserialize($serialized_object);
var_dump($data);

Biz daha önce tam olarak aynı çıktıyı alıyorum:

string 'callback_spl : a' (length=16)

object(a)[1]
  public 'value' => string '100' (length=3)

Autoloader ile belirlenen daha yüksek bir öncelik olarak spl_autoload_register ile tanımlı belirtmek görünüyor hangi unserialize_callback_func.


What else can I test ?
Oh, let's test setting both autoloading functions, but have the one registered by spl_autoload_register (i.e. the one with the highest priority) not actually load the class' definition :

$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';

ini_set('unserialize_callback_func', 'callback_no_spl');
function callback_no_spl($className)  {
    var_dump(__FUNCTION__ . ' : ' . $className);
    require dirname(__FILE__) . '/temp-2.php';
}

spl_autoload_register('callback_spl');
function callback_spl($className)  {
    var_dump(__FUNCTION__ . ' : ' . $className);
    //require dirname(__FILE__) . '/temp-2.php';        // We don't load the class' definition
}

$data = unserialize($serialized_object);
var_dump($data);

Bu kez, burada aldığımız çıktıya bulunuyor:

string 'callback_spl : a' (length=16)

string 'callback_no_spl : a' (length=19)

object(a)[1]
  public 'value' => string '100' (length=3)

Temelde:

  • The autoloading function registered with spl_autoload_register has been called
    • It dkimlik not load the class' definition
  • So the autoloading function registered with unserialize_callback_func has been called
    • And it dkimlik load the class' definition
    • Yani, biz düzgün un-serialized veriler elde ettik.


Now, let's come back to the code example you posted -- translated to my functions names, it would give us something like this, I suppose :

$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';

ini_set('unserialize_callback_func', 'callback_no_spl');
function callback_no_spl($className)  {
    var_dump(__FUNCTION__ . ' : ' . $className);
    //require dirname(__FILE__) . '/temp-2.php';        // We don't load the class' definition
}

spl_autoload_register('callback_spl');
function callback_spl($className)  {
    var_dump(__FUNCTION__ . ' : ' . $className);
    //require dirname(__FILE__) . '/temp-2.php';        // We don't load the class' definition
}

$data = unserialize($serialized_object);
var_dump($data);

Ve bu sefer, ben senin yaptığın gibi bir şey aynı tür olsun:

string 'callback_spl : a' (length=16)
string 'callback_no_spl : a' (length=19)
string 'callback_spl : a' (length=16)

( ! ) Warning: unserialize() [function.unserialize]: Function callback_no_spl() hasn't defined the class it was called for ...

object(__PHP_Incomplete_Class)[1]
  public '__PHP_Incomplete_Class_Name' => string 'a' (length=1)
  public 'value' => string '100' (length=3)

Ve, bu sefer:

  • The function registered with spl_autoload_register is called
    • Ve sınıf 'tanımını yüklemez
  • Then, the function registered with unserialize_callback_func is called
    • Ya sınıf 'zamanlarda tanım yüklemez ...
  • Like magic, the function registered with spl_autoload_register is called again !
    • Hala sınıf 'tanımını yüklemez
  • And boom, we get a warning saying that the function registered with unserialize_callback_func dkimlik not load the class' definition
    • Bu sadece callback_spl ikinci kez çağrıldıktan sonra olur Not!
    • Which seems to indicate that there is some kind of autoloading happening even if the function defined with unserialize_callback_func dkimlikn't load what it should have...

İtiraf etmeliyim ki, bu güzel ve zor hem de - ve bu neden oluyor çok mantıklı görünmüyor gibi, oldukça hiçbir fikrim yok ...


I suppose this strange behavior has to do with the fact that :

spl_autoload_register, herhalde bir "yığın / kuyruk" davranış unserialize_callback_func eski davranışı ile bazı müdahaleleri olabilir ...

unserialize () aslında unserializing veri önce yüklenen sınıf tanımı gerektirir. unserialize_callback_func sınıf tanımı yüklü değil denilen ve spl_autoload_call (unserialize için gerekli sınıfı yüklemek için kayıtlı tüm autoloaders) kullanmayı dener.