PHP_FUNCTION(str_pad)
{
/* Input arguments */
zend_string *input; /* Input string 输入字符串*/
zend_long pad_length; /* Length to pad to 填充到多长.*/ /* Helper variables */
size_t num_pad_chars; /* Number of padding characters (total - input size) 要填充进去的字符个数*/
char *pad_str = " "; /* Pointer to padding string */
size_t pad_str_len = 1; // 填充字符的个数
zend_long pad_type_val = STR_PAD_RIGHT; /* The padding type value 填充类型,左填充、右填充、左右填充。默认右填充*/
size_t i, left_pad=0, right_pad=0;
zend_string *result = NULL; /* Resulting string 返回值*/ if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sl|sl", &input, &pad_length, &pad_str, &pad_str_len, &pad_type_val) == FAILURE) {
return;
} /* If resulting string turns out to be shorter than input string,
we simply copy the input and return. */
/* 如果pad_length(参数2)小于等于输入字符串的长度,则返回原始的输入字符串。*/
if (pad_length < 0 || (size_t)pad_length <= ZSTR_LEN(input)) {
RETURN_STRINGL(ZSTR_VAL(input), ZSTR_LEN(input));
} /* 填充字符串长度为0,如:str_pad("abc", 10, ""),则Warning级别的错误。
填充字符串的默认长度为1,即str_pad("abc", 10),的情况下pad_str_len=1。*/
if (pad_str_len == 0) {
php_error_docref(NULL, E_WARNING, "Padding string cannot be empty");
return;
} /*pad_type只能为STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH 或 0, 1, 2*/
if (pad_type_val < STR_PAD_LEFT || pad_type_val > STR_PAD_BOTH) {
php_error_docref(NULL, E_WARNING, "Padding type has to be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH");
return;
} num_pad_chars = pad_length - ZSTR_LEN(input); // 需要被填充进去的字符的数量
if (num_pad_chars >= INT_MAX) { // num_pad_chars的最大值是2147483647。#define INT_MAX 2147483647
php_error_docref(NULL, E_WARNING, "Padding length is too long");
return;
} result = zend_string_safe_alloc(1, ZSTR_LEN(input), num_pad_chars, 0);
ZSTR_LEN(result) = 0; /* We need to figure out the left/right padding lengths. */
switch (pad_type_val) {
case STR_PAD_RIGHT:
left_pad = 0;
right_pad = num_pad_chars;
break; case STR_PAD_LEFT:
left_pad = num_pad_chars;
right_pad = 0;
break; // 左填充数量小于右,left_pad <= right_pad
case STR_PAD_BOTH:
left_pad = num_pad_chars / 2;
right_pad = num_pad_chars - left_pad;
break;
} /* First we pad on the left. */
/* 左填充:循环添加字符 */
for (i = 0; i < left_pad; i++)
ZSTR_VAL(result)[ZSTR_LEN(result)++] = pad_str[i % pad_str_len]; /* Then we copy the input string. */
/* 左填充完成后,附加输入字符串 */
memcpy(ZSTR_VAL(result) + ZSTR_LEN(result), ZSTR_VAL(input), ZSTR_LEN(input));
ZSTR_LEN(result) += ZSTR_LEN(input); /* Finally, we pad on the right. */
/* 右填充:循环添加字符串 */
for (i = 0; i < right_pad; i++)
ZSTR_VAL(result)[ZSTR_LEN(result)++] = pad_str[i % pad_str_len]; // 添加字符串结束标志'\0'
ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0'; // 返回新字符串
RETURN_NEW_STR(result);
}

php内置函数分析之str_pad()的更多相关文章

  1. map内置函数分析所得到的思路

    map:会根据提供的函数对指定序列做映射. map(func, *iterables) --> map object Make an iterator that computes the fun ...

  2. php内置函数分析之array_diff_assoc()

    static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_type) /* {{{ */ { uint ...

  3. php内置函数分析之array_combine()

    PHP_FUNCTION(array_combine) { HashTable *values, *keys; uint32_t pos_values = ; zval *entry_keys, *e ...

  4. php内置函数分析之ucwords()

    PHP_FUNCTION(ucwords) { zend_string *str; char *delims = " \t\r\n\f\v"; register char *r, ...

  5. php内置函数分析之strtoupper()、strtolower()

    strtoupper(): PHP_FUNCTION(strtoupper) { zend_string *str; ZEND_PARSE_PARAMETERS_START(, ) Z_PARAM_S ...

  6. php内置函数分析之ucfirst()、lcfirst()

    ucfirst($str) 将 str 的首字符(如果首字符是字母)转换为大写字母,并返回这个字符串. 源码位于 ext/standard/string.c /* {{{ php_ucfirst Up ...

  7. php内置函数分析之trim()

    官方手册中: 类似函数还有两个:ltrim() 和 rtrim().分别处理字符串的左侧.右侧. trim()的具体实现位于:ext/standard/string.c /* {{{ proto st ...

  8. php内置函数分析之array_fill_keys()

    PHP_FUNCTION(array_fill_keys) { zval *keys, *val, *entry; if (zend_parse_parameters(ZEND_NUM_ARGS(), ...

  9. php内置函数分析range()

    PHP_FUNCTION(range) { zval *zlow, *zhigh, *zstep = NULL, tmp; , is_step_double = ; double step = 1.0 ...

随机推荐

  1. android camera 摄像头预览画面变形

    问题:最近在处理一下camera的问题,发现在竖屏时预览图像会变形,而横屏时正常.但有的手机则是横竖屏都会变形. 结果:解决了预览变形的问题,同时支持前后摄像头,预览无变形,拍照生成的jpg照片方向正 ...

  2. oracle中over函数

    1.oracle中按一个字段分组排序后取第一条数据. SELECT * FROM (SELECT ROW_NUMBER() OVER(PARTITION BY 分组字段 ORDER BY 排序字符 D ...

  3. VS2015+OpenGL4.0开发编译时弹出错误:glaux.lib(tk.obj) : error LNK2019: 无法解析的外部符号 _sscanf,该符号在函数 _GetRegistrySysColors@8 中被引用

    一.问题描述: VS2015+OpenGL4.0开发编译时弹出如下所示的错误: 1>glaux.lib(tk.obj) : error LNK2019: 无法解析的外部符号 _sscanf,该符 ...

  4. leetcode349—Intersection of Two Arrays

    Given two arrays, write a function to compute their intersection. Example 1: Input: nums1 = [1,2,2,1 ...

  5. selenium自动化环境搭建(Windows)

    参考内容:虫师<selenium2自动化测试实战-基于python语言> 一.selenium介绍 selenium主要用于web应用程序的自动化测试,还支持所有基于web的管理任务自动化 ...

  6. SNAT和DNAT

    1.SNAT iptables防火墙 Centos6.6 64位 iptables 内网:eth0 172.16.4.1 外网:eth 112.112.112.112/24 当有用户访问公网时,修改用 ...

  7. 基于bootstrap的multiple-select下拉控件使用

    multiple-select是一款优秀的下拉菜单控件,能够支持单选和多选. 详细参考文档: JS组件系列——两种bootstrap multiselect组件大比拼 multiple-select ...

  8. 关于NLB的群集操作模式知识 (转载)

    单播:单播模式是指各节点的网络适配器被重新指定了一个虚拟MAC(由02-bf和群集IP地址组成确保此MAC的唯一性).由于所有绑定群集的网络适配器的MAC都相同,所以在单网卡的情况下,各节点之间是不能 ...

  9. Django Rest Framework源码剖析(七)-----分页

    一.简介 分页对于大多数网站来说是必不可少的,那你使用restful架构时候,你可以从后台获取数据,在前端利用利用框架或自定义分页,这是一种解决方案.当然django rest framework提供 ...

  10. Redis简介、安装、配置、启用学习笔记

    前一篇文章有介绍关系型数据库和非关系型数据库的差异,现在就来学习一下用的较广的非关系型数据库:Redis数据库 Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-v ...