2024 年 PHP 日本大会

strlen

(PHP 4, PHP 5, PHP 7, PHP 8)

strlen获取字符串长度

描述

strlen(string $string): int

返回给定 string 的长度。

参数

string

要测量长度的 string

返回值

string 的长度(以字节为单位)。

示例

示例 #1 strlen() 示例

<?php
$str
= 'abcdef';
echo
strlen($str); // 6

$str = ' ab cd ';
echo
strlen($str); // 7
?>

注释

注意:

strlen() 返回的是字符串的字节数,而不是字符数。

参见

添加注释

用户贡献的注释 7 条注释

rm dot nasir at hotmail dot com
8 年前
我想分享一些对 PHP 新手或初学者非常重要的事情,他们使用 UTF8 编码字符的字符串或阿拉伯语、波斯语、普什图语、达里语、简体中文、繁体中文、日语、越南语、乌尔都语、马其顿语、立陶宛语等语言。
正如手册所说:“strlen() 返回的是字符串的字节数,而不是字符数”,因此,如果您想获取 UTF8 字符串中的字符数,请使用 mb_strlen() 而不是 strlen()。

示例

<?php
// 下面的阿拉伯语(你好)字符串为:59 个字节和 32 个字符
$utf8 = "السلام علیکم ورحمة الله وبرکاته!";

var_export( strlen($utf8) ); // 59
echo "<br>";
var_export( mb_strlen($utf8, 'utf8') ); // 32
?>
joeri at sebrechts dot net
8 年前
在检查长度以确保值适合数据库字段时,请注意使用正确的函数。

有三种可能的情况

1. 最可能的情况:数据库列是 UTF-8,长度以 Unicode 代码点定义(例如,用于 utf-8 数据库的 mysql varchar(200))。

<?php
// 如果 php.ini default_charset 设置为 UTF-8(= 默认值),则可以
mb_strlen($value);
iconv_strlen($value);
// 始终可以
mb_strlen($value, "UTF-8");
iconv_strlen($value, "UTF-8");

// 错误,请勿使用:
strlen(utf8_decode($value)); // 对某些多字节字符无效
grapheme_strlen($value); // 统计 grapheme,而不是代码点
?>

2. 数据库列的长度以字节定义(例如,oracle 的 VARCHAR2(200 BYTE))。

<?php
// 可以,但假设 php.ini 中的 mbstring.func_overload 为 0(= 默认值)
strlen($value);
// 可以,强制以字节为单位计数
mb_strlen($value, "8bit")
?>

3. 数据库列使用其他字符集(UTF-16、ISO-8859-1 等),长度以字符/代码点定义。

查找使用的字符集,并将其显式传递给长度函数。

<?php
// 可以,支持的字符集:https://php.net/manual/en/mbstring.supported-encodings.php
mb_strlen($value, $charset);
// 可以,支持的字符集:https://www.gnu.org/software/libiconv/
iconv_strlen($value, $charset);
?>
jasonrohrer at fastmail dot fm
11 年前
PHP 的 strlen 函数在处理空字节 ('\0') 方面与 C strlen 函数的行为不同。

在 PHP 中,字符串中的空字节不计为字符串的结尾,任何空字节都包含在字符串的长度中。

例如,在 PHP 中

strlen( "te\0st" ) = 5

在 C 中,相同的调用将返回 2。

因此,PHP 的 strlen 函数可用于查找二进制字符串中的字节数(例如,base64_decode 返回的二进制数据)。
Daniel Klein
两年前
从 PHP 8.0 开始,将 null 传递给 strlen() 已被弃用。要检查空字符串(不包括 '0')

<?php
// PHP < 8.0
if (!strlen($text)) {
echo
'Blank';
}

// PHP >= 8.0
if ($text === null || $text === '')) {
echo
'empty';
}
vcardillo at gmail dot com
十二年前
我想说明,仅仅使用此函数不足以真正测试空字符串。原因是 <?php strlen(null); ?> 将返回 0。那么你怎么知道值是 null,还是真正的空字符串呢?

<?php
$foo
= null;
$len = strlen(null);
$bar = '';

echo
"Length: " . strlen($foo) . "<br>";
echo
"Length: $len <br>";
echo
"Length: " . strlen(null) . "<br>";

if (
strlen($foo) === 0) echo 'Null length is Zero <br>';
if (
$len === 0) echo 'Null length is still Zero <br>';

if (
strlen($foo) == 0 && !is_null($foo)) echo '!is_null(): $foo is truly an empty string <br>';
else echo
'!is_null(): $foo is probably null <br>';

if (
strlen($foo) == 0 && isset($foo)) echo 'isset(): $foo is truly an empty string <br>';
else echo
'isset(): $foo is probably null <br>';

if (
strlen($bar) == 0 && !is_null($bar)) echo '!is_null(): $bar is truly an empty string <br>';
else echo
'!is_null(): $foo is probably null <br>';

if (
strlen($bar) == 0 && isset($bar)) echo 'isset(): $bar is truly an empty string <br>';
else echo
'isset(): $foo is probably null <br>';
?>

// 输出开始
Length: 0
Length: 0
Length: 0

Null length is Zero
Null length is still Zero

!is_null(): $foo is probably null
isset(): $foo is probably null

!is_null(): $bar is truly an empty string
isset(): $bar is truly an empty string
// 输出结束

所以,如果您关心原始值是否为 null,则似乎需要 `is_null()` 或 `isset()` 以及 `strlen()`。
basil at gohar dot us
十四年前
我们刚刚遇到一个我们认为是 bug 的问题,但结果是 PHP 5.2 和 5.3 之间记录的行为差异。请看以下代码示例

<?php

$attributes
= array('one', 'two', 'three');

if (
strlen($attributes) == 0 && !is_bool($attributes)) {
echo
"We are in the 'if'\n"; // PHP 5.3
} else {
echo
"We are in the 'else'\n"; // PHP 5.2
}

?>

这是因为在 5.2 中,`strlen` 会自动将传递给它的任何内容强制转换为字符串,而将数组强制转换为字符串会产生字符串“Array”。在 5.3 中,这一点发生了变化,如 5.3 中向后不兼容的更改中的以下几点所述 (https://php.net/manual/en/migration53.incompatible.php)

“更新的内部参数解析 API 已应用于 PHP 5.3.x 附带的所有扩展。此参数解析 API 导致函数在传递不兼容的参数时返回 NULL。此规则有一些例外,例如 get_class() 函数,它将继续在出错时返回 FALSE。”

因此,在 PHP 5.3 中,`strlen($attributes)` 返回 NULL,而在 PHP 5.2 中,`strlen($attributes)` 返回整数 5。这可能会影响其他函数,因此,如果您突然遇到不同的行为或新的错误,请检查您是否已升级到 5.3(我们最近做到了),然后检查日志中是否存在类似这样的警告

strlen() expects parameter 1 to be string, array given in /var/www/sis/lib/functions/advanced_search_lib.php on line 1028

如果是这样,那么您很可能正在遇到这种行为变化。
John
七年前
这里有很多错误信息,我想纠正一下!许多人警告不要使用 `strlen()`,因为它“非常慢”。嗯,这在旧版本的 PHP 中可能是正确的。但是从 PHP7 开始,这绝对不再正确了。它现在超级快!

我创建了一个 20,000,000 字节的字符串(约 20 兆字节),并在循环中迭代了一亿次。每次循环迭代都会对那个非常非常长的字符串进行新的 `strlen()` 操作。

结果:在一亿次对 20 兆字节字符串的 `strlen()` 调用中,总共只花了 488 毫秒。即使我使字符串变小或变大,`strlen()` 调用也不会变慢/变快。`strlen()` 几乎是一个恒定时间、超快的操作。

因此,PHP7 要么将每个字符串的长度存储为一个字段,它可以始终简单地查找而无需计算字符。要么它缓存 `strlen()` 的结果,直到字符串内容实际发生变化。无论哪种方式,您现在都不必再担心 `strlen()` 的性能了。从 PHP7 开始,它速度非常快!

如果您想在您的机器上重现它,这里是完整的基准代码

<?php

$iterations
= 100000000; // 1 亿
$str = str_repeat( '0', 20000000 );

// 基准循环和变量赋值以计算循环开销
$start = microtime(true);
for(
$i = 0; $i < $iterations; ++$i ) {
$len = 0;
}
$end = microtime(true);
$loop_elapsed = 1000 * ($end - $start);

// 基准测试 strlen 循环
$len = 0;
$start = microtime(true);
for(
$i = 0; $i < $iterations; ++$i ) {
$len = strlen( $str );
}
$end = microtime(true);
$strlen_elapsed = 1000 * ($end - $start);

// 从 strlen() 速度计算中减去循环开销
$strlen_elapsed -= $loop_elapsed;

echo
"\nstring length: {$len}\ntest took: {$strlen_elapsed} milliseconds\n";

?>
To Top