问答中心分类: PHP使用$str[0]获取字符串的第一个字符
0
匿名用户 提问 1天 前

我想得到字符串的第一个字母,我注意到了$str[0]效果很好。我只是不确定这是否是“良好实践”,因为这种符号通常用于数组。这个特性似乎没有很好的文档记录,所以我想请你们告诉我,在各个方面,使用这个符号是否合适?
还是我应该坚持做好事substr($str, 0, 1)?
另外,我注意到花括号($str{0})同样有效。怎么回事?

8 Answers
0
Mara Morton 回答 1天 前

从PHP 5.3.0开始,{}语法就被弃用了。建议使用方括号。

VolkerK 回复 1天 前

文档。php。网络/语言。类型。一串:Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose. However, this syntax is deprecated as of PHP 5.3.0. Use square brackets instead, such as $str[42].

Marco Demaio 回复 1天 前

@VolkerK:在你提供的链接上,我注意到他们删除了PHP手册上只留下的注释:Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose.所以我想知道他们是否决定使用{}从PHP 6开始不再被弃用

Tino 回复 1天 前

@马可·德梅奥(MarcoDemaio)这个链接现在告诉了迈克尔·莫顿(MichaelMorton)所说的。

VolkerK 回复 1天 前

“没有弃用的迹象”-实际上,弃用消息已在304518版本中删除-The curly-brackets-string-index-accessor-syntax does not emit any deprecation notice, although the original notice have been on and off for PHP 5.x, it does not in the current version, thrus we should not label it as deprecated. Related to bug #52254svn。php。net/repository/phpdoc/en/trunk/language/types/…

Fr0zenFyr 回复 1天 前

从今天(2018年5月10日)起PHP文档:Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose.这种语法似乎会持续一段时间。

0
gattsbr 回答 1天 前

假设您只需要来自$\u POST部分的第一个字符,我们将其称为“type”。并且$u POST[‘type]当前是“Control”。如果在这种情况下,如果您使用$_POST['type'][0]substr($_POST['type'], 0, 1)你会得到C返回
但是,如果客户端要修改他们发送给您的数据,请从typetype[]例如,然后发送“Control”和“Test”作为此阵列的数据,$_POST['type'][0]现在将返回Control而不是C鉴于substr($_POST['type'], 0, 1)只会失败。
所以是的,使用$str[0],但这取决于周围环境。

Will B. 回复 1天 前

为了避免这个特殊问题,在任何一种情况下,都应该始终执行数据验证。if (true === is_string($_POST['type']))

0
John Parker 回答 1天 前

我唯一的疑问是,这种技术在多字节字符串上的适用性如何,但如果这不是一个考虑因素,那么我怀疑您已经涵盖在内了。(如有疑问,mb_substr()显然,这是一个安全的选择。)
然而,从全局角度来看,我想知道您需要多久访问一次字符串中的第n个字符才能将其作为关键考虑因素。

0
Sergey Burish 回答 1天 前

对于多字节(unicode)字符串,使用str[0]可能会引起麻烦。mb_substr()是一个更好的解决方案。例如:

$first_char = mb_substr($title, 0, 1);

这里有一些细节:获取UTF-8字符串的第一个字符

SunB 回复 1天 前

感谢您提供此解决方案!如果第一个字符是unicode,[]不起作用

0
Willy Stadnick 回答 1天 前

它会因资源而异,但您可以运行下面的脚本并亲自查看;)

<?php
$tests = 100000;

for ($i = 0; $i < $tests; $i++)
{
    $string = md5(rand());
    $position = rand(0, 31);

    $start1 = microtime(true);
    $char1 = $string[$position];
    $end1 = microtime(true);
    $time1[$i] = $end1 - $start1;

    $start2 = microtime(true);
    $char2 = substr($string, $position, 1);
    $end2 = microtime(true);
    $time2[$i] = $end2 - $start2;

    $start3 = microtime(true);
    $char3 = $string{$position};
    $end3 = microtime(true);
    $time3[$i] = $end3 - $start3;
}

$avg1 = array_sum($time1) / $tests;
echo 'the average float microtime using "array[]" is '. $avg1 . PHP_EOL;

$avg2 = array_sum($time2) / $tests;
echo 'the average float microtime using "substr()" is '. $avg2 . PHP_EOL;

$avg3 = array_sum($time3) / $tests;
echo 'the average float microtime using "array{}" is '. $avg3 . PHP_EOL;
?>

一些参考号(在旧的Coredou机器上)

$ php 1.php 
the average float microtime using "array[]" is 1.914701461792E-6
the average float microtime using "substr()" is 2.2536706924438E-6
the average float microtime using "array{}" is 1.821768283844E-6

$ php 1.php 
the average float microtime using "array[]" is 1.7251944541931E-6
the average float microtime using "substr()" is 2.0931363105774E-6
the average float microtime using "array{}" is 1.7225742340088E-6

$ php 1.php 
the average float microtime using "array[]" is 1.7293763160706E-6
the average float microtime using "substr()" is 2.1037721633911E-6
the average float microtime using "array{}" is 1.7249774932861E-6

似乎使用[]{}运营商或多或少是一样的。

Ellert van Koperen 回复 1天 前

很好的测试!来自一个3岁的Xeon的一些数字:使用“array[]”的平均浮点微时间是2.2427082061768E-7使用“substr()”的平均浮点微时间是3.9647579193115E-7使用“array{}”的平均浮点微时间是2.1522283554077E-7

PypeBros 回复 1天 前

为了获得准确的测量结果,你最好在环路外进行微时间测量,不要在同一个环路内混合使用不同的方法。

Willy Stadnick 回复 1天 前

@PypeBros你能详细介绍一下你的方法的优点吗?也许可以分享一下代码?谢谢

PypeBros 回复 1天 前

假设microtime()测量精度为p,即,microtime() - p < real time < microtime+p,正在进行before=mt(); 1000_testsA; after=mt()允许您以p/1000的精度计算1次迭代的执行。

PypeBros 回复 1天 前

不混合执行testAtestB在相同的循环中,意味着您能够检测例如以下事实:testB是缓存杀手testA缓存友好。当它们都在同一个循环中时,测量它们的计时非常相同,因为testB污染testA的缓存。

PypeBros 回复 1天 前

类似地,我会避免在测试循环中生成字符串或随机数,并将它们准备在附近的数组中。

Mark Amery 回复 1天 前

-1; 撇开有问题的计时机制不谈(最好对许多操作计时,而不是一次对一个操作计时;我读到这篇文章时担心的是,仅仅是执行microtime()呼叫将弥补大部分时间差,尽管实验上似乎不正确),没有理由关心这里微小的速度差。这是百万分之一秒的几分之一;这是什么时候曾经有什么关系吗?