PHP源码阅读笔记一(explode和implode函数分析)
PHP源码阅读笔记一
一、explode和implode函数
array explode ( string separator, string string [, int limit] )
此函数返回由字符串组成的数组,每个元素都是 string 的一个子串,它们被字符串 separator 作为边界点分割出来。如果设置了 limit 参数,则返回的数组包含最多 limit 个元素,而最后那个元素将包含 string 的剩余部分。
此函数的时间复杂度应该是O(strlen(separator) * strlen(string))
其实现过程基本上是遍历字符串string,将它与separator比较,如果相同,则写入hash表,并将string的指针移到新的位置(即每一个separator的右边);
另外,对于limit小于0的情况有特殊处理
本函数实现主要是依赖于php_memnstr函数,在php.h文件中我们可以看到它的定义,
#define php_memnstr zend_memnstr
其真正的函数是zend_memnstr,在Zend/zend_operators.h文件的217行,可以看到它的定义,其实现主要是一个while循环和两个C语言的函数memchr和memcmp
php源代码如下:
PHP_FUNCTION(explode)
{
char *str, *delim;
int str_len = 0, delim_len = 0;
long limit = LONG_MAX; /* No limit */
zval zdelim, zstr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &delim, &delim_len, &str, &str_len, &limit) == FAILURE) {
return;
}
if (delim_len == 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");
RETURN_FALSE;
}
array_init(return_value);
if (str_len == 0) {
if (limit >= 0) {
add_next_index_stringl(return_value, "", sizeof("") - 1, 1);
}
return;
}
ZVAL_STRINGL(&zstr, str, str_len, 0);
ZVAL_STRINGL(&zdelim, delim, delim_len, 0);
if (limit > 1) {
php_explode(&zdelim, &zstr, return_value, limit);
} else if (limit < 0) {
php_explode_negative_limit(&zdelim, &zstr, return_value, limit);
} else {
add_index_stringl(return_value, 0, str, str_len, 1);
}
}
string implode ( string glue, array pieces )
此函数返回一个以glue字符串连接的pieces数组的各元素的字符串。
此函数可以是以一个数组为参数,可以是以一个数组和一个字符串为参数,并且字符串和数组的顺序可以改变,这些在程序中都有针对每种情况的特殊处理,如下代码:
1 |
if (argc == 1) { |
最后数组都会赋值给arr,分隔字符串赋值给delim,没有的置为””
就是一个遍历数组,并连接字符串的过程,只是这个过程中使用了smart_str相关函数(更多相关请移步 ),针对不同的类型作了不同的连接操作(如果是数字还需要将数字转化成字符串,这些在smart_str中都有相关函数处理)
转载请以链接形式注明原始出处和作者,谢绝不尊重版权者抄袭!
PHP源码阅读笔记一(explode和implode函数分析)的更多相关文章
- CI框架源码阅读笔记5 基准测试 BenchMark.php
上一篇博客(CI框架源码阅读笔记4 引导文件CodeIgniter.php)中,我们已经看到:CI中核心流程的核心功能都是由不同的组件来完成的.这些组件类似于一个一个单独的模块,不同的模块完成不同的功 ...
- CI框架源码阅读笔记4 引导文件CodeIgniter.php
到了这里,终于进入CI框架的核心了.既然是“引导”文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.c ...
- CI框架源码阅读笔记3 全局函数Common.php
从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...
- CI框架源码阅读笔记2 一切的入口 index.php
上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里再次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中, ...
- 源码阅读笔记 - 1 MSVC2015中的std::sort
大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格 ...
- Three.js源码阅读笔记-5
Core::Ray 该类用来表示空间中的“射线”,主要用来进行碰撞检测. THREE.Ray = function ( origin, direction ) { this.origin = ( or ...
- AQS源码阅读笔记(一)
AQS源码阅读笔记 先看下这个类张非常重要的一个静态内部类Node.如下: static final class Node { //表示当前节点以共享模式等待锁 static final Node S ...
- libevent源码阅读笔记(一):libevent对epoll的封装
title: libevent源码阅读笔记(一):libevent对epoll的封装 最近开始阅读网络库libevent的源码,阅读源码之前,大致看了张亮写的几篇博文(libevent源码深度剖析 h ...
- Mina源码阅读笔记(四)—Mina的连接IoConnector2
接着Mina源码阅读笔记(四)-Mina的连接IoConnector1,,我们继续: AbstractIoAcceptor: 001 package org.apache.mina.core.rewr ...
随机推荐
- AIDL-Android接口描述语言实现跨进程通讯
在Android中, 每个应用程序都可以有自己的进程. 在写UI应用的时候, 经常要用到Service. 在不同的进程中, 怎样传递对象呢? 显然, Java中不允许跨进程内存共享. 因此传递对象, ...
- linux Kernell crash dump------kdump 的安装设置+Linux系统崩溃的修复解决过程+mysql+kvm
http://www.ibm.com/developerworks/cn/linux/l-cn-dumpanalyse/https://www.kernel.org/pub/linux/utils/k ...
- oracle db mos文章 翻译系列
http://blog.csdn.net/msdnchina/article/details/38377125
- VS的一部分快捷键
快捷键 功能CTRL + SHIFT + B 生成解决方案CTRL + F ...
- SoundPool没有声音的问题
在项目中需要播放一个提示,很短的一个声音,Android中播放声音有两种方式:MediaPlayer和SoundPool.相对来说SoundPool比较轻量级一些,多用在播放比较短急的声音,Media ...
- PHP中将数据库中的数据显示在网页
最近没事把以前的东西感觉还可以的又简单的看了以下,因为还在学习新的东西,所以,发表的博客也不是很多,也许是有感而发吧. 这次讲的是mysql数据库中的数据使用php如何显示在网页中.首先,先建好自己的 ...
- C#扫盲之:静态成员、静态方法、静态类、实例成员及区别
文章目录 1.静态成员.实例成员 2.静态类 3.类的静态成员和非静态成员区别 --------------------------------------分割线------------------- ...
- CodeFile与CodeBehind的区别
引自:http://blog.163.com/wentworth0119@126/blog/static/17321924220122852720103/ asp.net发布项目之后 存在" ...
- Hibernate注解错误之- org.hibernate.MappingException: Could not determine type for:
Hibernate 注解 @OneToOne 时候,出现以下错误,经调试,发现 注解要么全部放在字段上,要么全部放在get方法上,不能混合使用! org.hibernate.MappingExcept ...
- 对进度条progressbar的调整
进度条的理解,感觉这个进度条不是那么简单,系统给我们定制了几个普通的,但是如果还需要有更加好的效果,需要自己去调试. <ProgressBar android:layout_width=&quo ...