在采用PHP开发中字符串处理和数组处理是我们最常见的功能,今天我们就通过实例来学习下在PHP扩展中字符串是如何处理的。
首先看下面一段PHP代码。
- <?php
- function str_concat($prefix, $string) {
- $len = strlen($prefix);
- $substr = substr($string, 0, $len);
- if ($substr != $prefix) {
- return $prefix." ".$string;
- } else {
- return $string;
- }
- }
- echo str_concat("hello", "word");
- echo "\n";
- echo str_concat("hello", "hello bo56.com");
- echo "\n";
- ?>
上述str_concat方法主要有两个功能:
①当字符串不包含指定前缀字符串时,把前缀字符串和被检测字符合并返回。
②当字符串包含指定前缀字符串时,原样返回。
接下来我们看下在如何在PHP扩展中开发str_concat功能,这里我们继续把str_concat函数写在say的扩展中,代码如下:
- PHP_FUNCTION(str_concat)
- {
- zend_string *prefix, *subject, *result;
- zval *string;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz", &prefix, &string) == FAILURE) {
- return;
- }
- subject = zval_get_string(string);
- if (zend_binary_strncmp(ZSTR_VAL(prefix), ZSTR_LEN(prefix), ZSTR_VAL(subject), ZSTR_LEN(subject), ZSTR_LEN(prefix)) == 0) {
- RETURN_STR(subject);
- }
- result = strpprintf(0, "%s %s", ZSTR_VAL(prefix), ZSTR_VAL(subject));
- RETURN_STR(result);
- }
代码解读:
zend_string是PHP7新增的结构。结构如下:
- struct _zend_string {
- zend_refcounted_h gc; /*gc信息*/
- zend_ulong h; /* hash value */
- size_t len; /*字符串长度*/
- char val[1]; /*字符串起始地址*/
- };
在Zend/zend_string.h提供了一些zend_string处理的一些方法。ZSTR_开头的宏方法是zend_string结构专属的方法。主要有如下几个:
- #define ZSTR_VAL(zstr) (zstr)->val
- #define ZSTR_LEN(zstr) (zstr)->len
- #define ZSTR_H(zstr) (zstr)->h
- #define ZSTR_HASH(zstr) zend_string_hash_val(zstr)
ZSTR_VAL
、ZSTR_LEN ZSTR_H
宏方法分别对应zend_string
结构的成员。ZSTR_HASH
是获取字符串的hash值,如果不存在,就调用hash函数生成一个。
代码中故意把第二个参数转换成zval。主要是为了展现zend为我们提供了一系列的操作方法。如,zval_get_string
, zend_binary_strncmp
。
这些方法在Zend/zend_operators.h文件中。更多宏方法请查看 Zend/zend_API.h中的相关代码。