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. 安装Jenkins服务

    1.下载Jenkins 下载地址:https://jenkins.io/download/ 选择rpm包 2.启动服务 [root@node1 ~]# rpm -ivh jenkins-2.138.3 ...

  2. 大数据入门第二十天——scala入门(二)scala基础02

    一. 类.对象.继承.特质 1.类 Scala的类与Java.C++的类比起来更简洁 定义: package com.jiangbei //在Scala中,类并不用声明为public. //Scala ...

  3. python 回溯法 子集树模板 系列 —— 9、旅行商问题(TSP)

    问题 旅行商问题(Traveling Salesman Problem,TSP)是旅行商要到若干个城市旅行,各城市之间的费用是已知的,为了节省费用,旅行商决定从所在城市出发,到每个城市旅行一次后返回初 ...

  4. Keras实现风格迁移

    风格迁移 风格迁移算法经历多次定义和更新,现在应用在许多智能手机APP上. 风格迁移在保留目标图片内容的基础上,将图片风格引用在目标图片上. 风格本质上是指在各种空间尺度上图像中的纹理,颜色和视觉图案 ...

  5. Maven学习第1期---Maven简单介绍

    前言 Hadoop的MapReduce环境是一个复杂的编程环境,所以我们要尽可能地简化构建MapReduce项目的过程.Maven是一个很不错的自动化项目构建工具,通过Maven来帮助我们从复杂的环境 ...

  6. Android与Libgdx入门实例

    本文讲解如何实现Android与Libgdx各自的Hello World过程. 1. Android版Hello World 点击Eclipse快捷方式,选择New Android Applicati ...

  7. python中的and和or用法

    在python中and和or返回的值并不是True和false这么简单.虽然他们看上去和c++中的&&和||有些相似.在了解and和or之前,我们先要了解python中的True和Fa ...

  8. 【ORACLE】oracle数据库用户密码复杂度配置

    -- 设置密码复杂度 SQL> @ /u01/app/oracle/product/11.2.0/db_1/rdbms/admin/utlpwdmg.sql -- 测试 SQL> alte ...

  9. 《Effective Java》学习笔记 ——异常

    充分发挥异常的优点,可以提高程序的可读性.可靠性和可维护性. 第57条 只针对异常的情况才使用异常 第58条 对可恢复的情况使用受检异常,对编程错误使用运行时异常 * 如果期望调用者能够适当的恢复,使 ...

  10. C#_添加xml文件

    引用:System.Xml; XmlDocument doc = new XmlDocument(); XmlElement Root = doc.CreateElement("Root&q ...