2011-01-01 4 views
5

Ho letto le interfacce comunemente utilizzate di PHP dal SPL, ad esempio Iterator, Countable e ArrayAccess. Tuttavia, non capisco esattamente come funzionano.Come funziona ArrayAccess?

Le loro implementazioni modificano le funzionalità di base di PHP, ad esempio l'overloading dell'operatore di array []?

Ho letto anche l'estensione dell'operatore, che offre la possibilità di sovraccaricare altri operatori allo stesso modo dei linguaggi di livello inferiore. Poiché l'estensione dell'operatore modifica chiaramente il core PHP, mi chiedevo se lo ArrayAccess agisse nello stesso modo dietro le quinte?

Sono uno che armeggia, di conseguenza trovo difficile usare qualcosa senza sapere cosa c'è sotto il cofano.

+0

Questo non risponde alla tua domanda. Ma dal momento che stai chiedendo informazioni su internals, finirai qui: http://svn.php.net/repository/php/php-src/branches/PHP_5_3/Zend/ - quindi potresti anche dare un'occhiata a zend_interfaces. c e ../ext/spl/ ora. – mario

risposta

10

Le estensioni PHP e PHP sono basate su Zend Engine. Esporre la funzionalità di Zend Engine a user-land (script PHP) e aggiungere funzionalità proprie, che sono esposte a user-land o ad altre estensioni PHP.

Zend motore fornisce un modello oggetto con un modo per accedere dimensioni dell'oggetto (la funzionalità esposte da ArrayAccess) e un meccanismo di iterazione generale che viene utilizzato per scorrere oggetti (idem per Iterator). Questo modello a oggetti è costituito da un numero di gestori che PHP e qualsiasi estensione possono sostituire per un tipo di oggetto (zend object handlers). Sul suo modello a oggetti, il motore Zend implementa un tipo standard di oggetti (gli "oggetti zend"); ogni oggetto segue la struttura dei dati zend_object e ogni classe - che è un concetto che l'interfaccia oggetto di basso livello non conosce oltre a fornire un modo per recuperarlo - tramite una struttura zend_class_entry.

ArrayAccess non è in realtà un'interfaccia SPL; è definito nel motore Zend stesso. I manipolatori di basso livello degli oggetti zend sono implementati nei gestori di livello basso read_dimension/write_dimension/write_dimension/ in modo tale da controllare se l'oggetto implementa tale interfaccia e chiamare i rispettivi metodi in tal caso (vedere here).

Iterator non è un'interfaccia SPL; è anche definito nel motore Zend. In questo caso, il supporto per questa interfaccia è fatto a un livello leggermente più alto. I gestori di oggetti di basso livello non conoscono l'iterazione dell'oggetto; questa è una proprietà di oggetti Zend. La struttura zend_class_entry ha qui due membri rilevanti: il campo iterator_funcs e il campo get_iterator. Questi definiscono le operazioni e lo stato dell'iteratore e come creare un nuovo iteratore. In particolare, per Iterator, quando una classe è registrata con il runtime, viene controllato se implementa tale interfaccia e, in caso affermativo, i campi rilevanti nella variabile zend_class_entry per quella classe sono impostati su metodi nativi che collegano l'interfaccia di iterazione nativa a PHP metodi. Se si scrive un'estensione PHP, si può scegliere di scrivere un iteratore nativo (che implementa i metodi di iterazione in modo nativo) o, proprio come in user-land, implementare Iterator e scrivere metodi PHP (in questo caso, metodi PHP nativi) per le varie operazioni, come descrive l'interfaccia.

L'interfaccia Countable è l'unica in realtà un'interfaccia SPL; il motore Zend non ne sa nulla. La sua funzionalità deriva dal fatto che l'implementazione di count function verifica la sua presenza e chiama il metodo count se l'interfaccia esiste.

L'interno dell'operatore funziona con un'impostazione più bassa.In fase di esecuzione, scrive direttamente nella memoria di Zend Engine e sostituisce i gestori degli opcode che compongono il codice PHP (in modo che ora ad esempio lo ZEND_ASSIGN_ADD abbia una nuova implementazione nativa, che rimanda a qualche funzione/metodo PHP che l'utente può scegliere) .

+0

Wow, grazie ** Artefacto ** per quella risposta esaustiva, ha sicuramente colmato le lacune della mia comprensione. Ho decisamente molto da imparare. – Dan