php扩展开发笔记(1)创建类的数组属性
初始化一个类非常容易,例如下面的代码
MYCLASS_PROTERTY_* 这个相关是 define 的宏字符串
<code>zend_class_entry *myclass_ce; zend_function_entry myclass_methods[] = { PHP_FE_END }; PHP_MINIT_FUNCTION(myext) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, <span>"MyClass"</span>, myclass_methods); myclass_ce = zend_register_internal_class(&ce TSRMLS_CC); zend_<span>declare</span>_class_constant_string(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_VERSION), PHP_SLIM_VERSION); zend_<span>declare</span>_property_null(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_CONTAINER), ZEND_ACC_PUBLIC TSRMLS_CC); zend_<span>declare</span>_property_null(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_APPS), ZEND_ACC_STATIC|ZEND_ACC_PROTECTED TSRMLS_CC); zend_<span>declare</span>_property_null(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_NAME), ZEND_ACC_PROTECTED TSRMLS_CC); zend_<span>declare</span>_property_null(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_ERROR), ZEND_ACC_PROTECTED TSRMLS_CC); zend_<span>declare</span>_property_null(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_NOTFOUND), ZEND_ACC_PROTECTED TSRMLS_CC); zend_<span>declare</span>_property_null(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_MIDDLEWARE), ZEND_ACC_PROTECTED TSRMLS_CC); <span>return</span> SUCCESS; }</code>
以上的代码都是一些简单的属性。
当想要给myclass这个类初始化一个数组的属性的时候,失败了,相对于php的代码如下
<code><span><span>class</span><span>MyClass</span> { public $myArray = array<span>()</span>; } /* 对应的<span>C</span>代码 */ zval *myArray; <span>MAKE_STD_ZVAL</span><span>(<span>myArray</span>)</span>; array_init<span>(<span>myArray</span>)</span>; zend_declare_property<span>(<span>myclass_ce</span>, <span>ZEND_STRL(MYCLASS_PROTERTY_NAME_MYCLASS)</span>, <span>myArray</span>, <span>ZEND_ACC_PUBLIC</span><span>TSRMLS_CC</span>)</span>;</span></code>
上面这段C代码变异的时候并没有发现什么问题,在执行 new MyClass() 的时候就出现问题了,报错如下:
<code>Internal zval<span>'s</span> can<span>'t</span> be arrays, objects <span>or</span> resources</code>
翻看zend的源代码如下:
<code><span>if</span> (ce-><span><span>type</span> & <span>ZEND_INTERNAL_CLASS</span>) <span>{ <span>switch</span>(<span>Z_TYPE_P(property)</span>) { <span>case</span><span>IS_ARRAY</span>: <span>case</span><span>IS_CONSTANT_ARRAY</span>: <span>case</span><span>IS_OBJECT</span>: <span>case</span><span>IS_RESOURCE</span>: <span>zend_error</span>(<span>E_CORE_ERROR</span>, "<span>Internal</span><span>zval's</span><span>can't</span><span>be</span><span>arrays</span>, <span>objects</span><span>or</span><span>resources</span>"); <span>break</span>; <span>default</span>: <span>break</span>; }</span></span> }</code>
当我们在调用zend_register_internal_class的时候,myclass_ce 已经初始化为ZEND_INTERNAL_CLASS了,而此时的zend_declare_property的myArray参数则是IS_ARRAY类型的,所以产生了这样的错误。
为什么会产生这样的错误呢?
我搜索下得到的结果是:http://grokbase.com/t/php/php-internals/07a4b14xvb/php-dev-how-declare-protected-array-property-at-internal-class-properly 这个是2007年的结果,我这个是采用的php5.4版本的,暂时还是有这个问题的,文中也给了变相实现数组属性的方法,通过在构造函数里面实现。
<code>PHP_METHOD(myclass, __construct) { zval <span>*apps</span>, <span>*pThis</span>; pThis = getThis(); MAKE_STD_ZVAL(apps); array_init(apps); add_property_zval_ex(pThis, ZEND_STRL(SLIM_SLIM_PROTERTY_NAME_APPS), apps); }</code>
这种实现的方式对应的php代码
<code><span><span>class</span><span>MyClass</span> {</span><span><span>function</span><span>__construct</span><span>()</span> {</span><span>$this</span>->app = <span>array</span>(); } }</code>
以上就介绍了php扩展开发笔记(1)创建类的数组属性,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Notis PHP: Tryingtogetpropertyofnon-object-Solution Semasa proses pembangunan PHP, kita mungkin menghadapi mesej ralat biasa: Tryingtogetpropertyofnon-object (cuba mendapatkan sifat bukan objek). Ralat ini biasanya disebabkan apabila kita cuba mengakses harta (atau memanggil kaedah) pada pembolehubah yang bukan jenis objek. Artikel ini akan memperkenalkan anda kepada ini

Penggunaan pengisytiharan Oracle termasuk pengisytiharan berubah-ubah, pengisytiharan malar, pengisytiharan kursor dan pengisytiharan subrutin. Pengenalan terperinci: 1. Pengisytiharan pembolehubah, dalam blok PL/SQL, anda boleh menggunakan pernyataan DECLARE untuk mengisytiharkan pembolehubah; set hasil pertanyaan diproses dalam blok; 4. Pengisytiharan subrutin ialah blok kod boleh guna semula yang ditakrifkan dalam blok PL/SQL.

Semasa menulis kod dalam PHP, kami mungkin menghadapi mesej ralat "Notis: Undefinedproperty". Ralat ini bermakna kami sedang mengakses sifat yang tidak ditentukan, biasanya kerana sifat tersebut belum dimulakan dalam kod. Jadi, bagaimana untuk menyelesaikan masalah ini? Berikut ialah beberapa penyelesaian yang mungkin: Mulakan sifat Ini adalah cara paling mudah untuk menyelesaikan masalah ini. Memulakan sifat dalam kod secara eksplisit memastikan ia ditakrifkan sebelum digunakan. Contohnya: kelas

Rangka kerja pelaksanaan PHP: Tutorial pengenalan ZendFramework ZendFramework ialah rangka kerja tapak web sumber terbuka yang dibangunkan oleh PHP dan kini diselenggara oleh ZendTechnologies menggunakan corak reka bentuk MVC dan menyediakan satu siri perpustakaan kod boleh guna semula untuk melaksanakan aplikasi Web2.0 dan Web Serve. ZendFramework sangat popular dan dihormati oleh pembangun PHP dan mempunyai pelbagai jenis

Cara menggunakan ACL (AccessControlList) untuk kawalan kebenaran dalam Rangka Kerja Zend Pengenalan: Dalam aplikasi web, kawalan kebenaran ialah fungsi penting. Ia memastikan bahawa pengguna hanya boleh mengakses halaman dan ciri yang dibenarkan untuk mereka akses dan menghalang akses yang tidak dibenarkan. Rangka kerja Zend menyediakan cara yang mudah untuk melaksanakan kawalan kebenaran, menggunakan komponen ACL (AccessControlList). Artikel ini akan memperkenalkan cara menggunakan ACL dalam Rangka Kerja Zend

Vue ialah rangka kerja JavaScript yang popular untuk membina antara muka pengguna. Semasa proses pembangunan, kami mungkin menghadapi pelbagai ralat dan pengecualian. Salah satu ralat biasa ialah "TypeError:Cannotreadproperty'XXX'ofnull". Dalam artikel ini, kami akan meneroka punca ralat ini dan cara membetulkannya. Pertama, mari kita fahami sebab di sebalik ralat ini. Apabila kita cuba mengakses harta atau kaedah objek, jika pasangan itu

TypeError:Cannotreadproperty'$XXX'ofudefined dalam Vue, apakah penyelesaiannya? Dalam pembangunan Vue, ralat seperti TypeError:Cannotreadproperty'$XXX'ofundefined sering ditemui. Ralat ini biasanya disebabkan oleh menggunakan sifat atau kaedah yang tidak ditentukan dalam contoh Vue. Apabila ralat ini berlaku, kita perlu

TypeError:Cannotreadproperty'XXX'ofudefined dalam Vue, apakah yang perlu saya lakukan? Bagi pembangun bahagian hadapan yang menggunakan Vue untuk membangunkan, mereka mungkin sering menghadapi ralat TypeError:Cannotreadproperty'XXX'fundefined semasa proses pembangunan. Ralat ini biasanya berlaku apabila cuba mengakses harta yang tidak ditentukan. wujud
