字串處理是我們常用的操作,而zend 封裝了很多關於字串運算相關的宏,先看下ZVAL_STRING 和ZVAL_STRINGL
<code><span>#define ZVAL_STRING(z, s, duplicate) do { \</span><span>const</span><span>char</span> *__s=(s); \ zval *__z = (z); \ Z_STRLEN_P(__z) = <span>strlen</span>(__s); \ Z_STRVAL_P(__z) = (duplicate?estrndup(__s, Z_STRLEN_P(__z)):(<span>char</span>*)__s);\ Z_TYPE_P(__z) = IS_STRING; \ } <span>while</span> (<span>0</span>) <span>#define ZVAL_STRINGL(z, s, l, duplicate) do { \</span><span>const</span><span>char</span> *__s=(s); <span>int</span> __l=l; \ zval *__z = (z); \ Z_STRLEN_P(__z) = __l; \ Z_STRVAL_P(__z) = (duplicate?estrndup(__s, __l):(<span>char</span>*)__s);\ Z_TYPE_P(__z) = IS_STRING; \ } <span>while</span> (<span>0</span>)</code>
因為php 內部很多字串運算(例如substr)最後都是給予這樣的宏來操作的,所以在這裡了解這兩個宏非常重要。
ZVAL_STRINGL 在處理的時候,因為給了 length 參數,所以不需要在使用 strlen 來求字串的長度了, 性能上有所提升。
前面在常用的zend api 裡面應該說過了,關於estrndup 也都是封裝了一層的,在php 擴展開發的時候,盡量使用系統封裝的函數,這樣可以優化內存,降低內存洩漏等風險,有幾個e* 開發的函數,可以看之前的相關文章。
estrndup 定義
<code><span>#define estrndup(s, length) _estrndup((s), (length) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)</span></code>
_estrndup 定義
<code> ZEND_API <span>char</span> *_estrndup(<span>const</span><span>char</span> *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { <span>char</span> *p; <span>#ifdef ZEND_SIGNALS</span> TSRMLS_FETCH(); <span>#endif</span> HANDLE_BLOCK_INTERRUPTIONS(); p = (<span>char</span> *) _emalloc(length+<span>1</span> ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); <span>if</span> (UNEXPECTED(p == NULL)) { HANDLE_UNBLOCK_INTERRUPTIONS(); <span>return</span> p; } <span>memcpy</span>(p, s, length); p[length] = <span>0</span>; HANDLE_UNBLOCK_INTERRUPTIONS(); <span>return</span> p; }</code>
可以自行搜尋關於 _emalloc 等相關函數定義。
以上就介紹了php擴充開發筆記(6)ZVAL_STRING 和 ZVAL_STRINGL,包含了方面的內容,希望對PHP教學有興趣的朋友有幫助。