ZVAL_STRING 和 ZVAL_STRINGL

字符串處理是我們常用的操作,而 zend 封裝了很多關於字符串操作相關的宏,先看下 ZVAL_STRING 和 ZVAL_STRINGL

#define ZVAL_STRING(z, s, duplicate) do {	\
		const char *__s=(s);				\
		zval *__z = (z);					\
		Z_STRLEN_P(__z) = strlen(__s);		\
		Z_STRVAL_P(__z) = (duplicate?estrndup(__s, Z_STRLEN_P(__z)):(char*)__s);\
		Z_TYPE_P(__z) = IS_STRING;			\
	} while (0)

#define ZVAL_STRINGL(z, s, l, duplicate) do {	\
		const char *__s=(s); int __l=l;			\
		zval *__z = (z);						\
		Z_STRLEN_P(__z) = __l;					\
		Z_STRVAL_P(__z) = (duplicate?estrndup(__s, __l):(char*)__s);\
		Z_TYPE_P(__z) = IS_STRING;				\
	} while (0)

因爲 php 內部很多字符串操作(例如 substr)最後都是給予這樣的宏來操作的,所以在這裏瞭解這兩個宏非常重要。

ZVAL_STRINGL 在處理的時候,因爲給了 length 參數,所以不需要在使用 strlen 來求字符串的長度了, 性能上有所提升。

關於 estrndup 也都是封裝了一層的,在 php 擴展開發的時候,儘量使用系統封裝的函數,這樣可以優化內存,降低內存泄漏等風險

ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
	char *p;
#ifdef ZEND_SIGNALS
	TSRMLS_FETCH();
#endif

	HANDLE_BLOCK_INTERRUPTIONS();

	p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
	if (UNEXPECTED(p == NULL)) {
		HANDLE_UNBLOCK_INTERRUPTIONS();
		return p;
	}
	memcpy(p, s, length);
	p[length] = 0;
	HANDLE_UNBLOCK_INTERRUPTIONS();
	return p;
}

有幾個 e* 開發的函數 具體參看




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章