【问题标题】:PHP: Check if variable is type of string AND is not empty string?PHP:检查变量是否是字符串类型并且不是空字符串?
【发布时间】:2015-11-05 13:56:56
【问题描述】:

我需要检查传递的变量是否为字符串类型,并且它不为空。我有以下功能:

function isNonEmptyStr($var)
{
    if(isset($var)) {
        if(is_string($var)) {
            if(strlen($var) > 0) {
                return true;
            }
        }
    }
    return false;
}

我期望的结果:

echo(isNonEmptyStr(''));// false
echo(isNonEmptyStr(' '));// true
echo(isNonEmptyStr('a'));// true
echo(isNonEmptyStr('1'));// true
echo(isNonEmptyStr(1));// false
echo(isNonEmptyStr(0));// false
echo(isNonEmptyStr(0.0));// false
echo(isNonEmptyStr(0.1));// false
echo(isNonEmptyStr(array()));// false
echo(isNonEmptyStr(new myObj()));// false
echo(isNonEmptyStr(true));// false
echo(isNonEmptyStr(false));// false
echo(isNonEmptyStr(null));// false

该功能运行良好。

我的问题:有没有办法在不影响结果的情况下提高函数性能?

我说的是“微优化”(我非常频繁地使用这个功能)。

编辑

对于那些询问的人:

echo(isNonEmptyStr(0));// should return false, because it's not a string
echo(isNonEmptyStr(1));// should return false, because it's not a string
echo(isNonEmptyStr('0'));// should return true, because it's a non-empty string
echo(isNonEmptyStr('1'));// should return true, because it's a non-empty string

注意: 一个非空字符串 = 如果用 strlen() 函数测试它会返回 > 0

【问题讨论】:

  • 如果isset(),你可以摆脱它,因为它总是由你的函数定义设置
  • 如果你已经知道它是一个字符串,可以使用!empty($var)
  • 如果你使用它来获取和发布变量,它们将永远是字符串。
  • 这不是更适合代码审查吗?
  • 在这个线程中有多少人do not understand empty...

标签: php performance micro-optimization


【解决方案1】:

这是一个简单的小基准测试脚本,您可以对其进行修改以查看最有效的方法。我只是尝试了同一件事的一些变体,第一个是最快的,但它们基本上都是一样的。而且真的没有更简单的方法来编写它。

此外,$val === ''empty($val) 稍快,而且对您来说更准确。

此外,既然这基本上是一个单行,为什么不直接削减使其成为函数的开销并直接调用is_string($val) && $val !== ''。它并没有太大的区别,但它在数百万次迭代中很明显,但我怀疑这个过程将成为你任何代码中的主要瓶颈......

function is_non_empty_string_1($val)
{
    return is_string($val) && $val !== '';
}

function is_non_empty_string_2($val)
{
    return gettype($val) === 'string' && $val !== '';
}

function is_non_empty_string_3($val)
{
    switch (true) {
        case !is_string($val): return false;
        case $val === '': return false;
    }

    return true;
}

$values = array('', '1', new stdClass(), 1, 2, 3, 999, array(), array());
$runs = 2000000;


function benchmark($test, $values, $runs, $func)
{
    $time = time();
    for ($i = 0; $i < $runs; $i++) {
        foreach ($values as $v) {
            $func($v);
        }
    }
    echo $test . '. ' . (time() - $time) . PHP_EOL;
}

benchmark(1, $values, $runs, 'is_non_empty_string_1');
benchmark(2, $values, $runs, 'is_non_empty_string_2');
benchmark(3, $values, $runs, 'is_non_empty_string_3');

结果:

1. 5
2. 6
3. 6

【讨论】:

  • @deceze 感谢您的努力和解释。到目前为止,最快的函数是 Flosculus 的_non_empty_string_1($val),虽然这个函数和你的差别很小
  • FWIW:缺少我经常看到的空字符串,strlen &gt; 0 而不是 !== ''
【解决方案2】:
  1. 您不需要在函数内调用isset,因为您正在测试函数签名中定义的变量。如果你不向函数传递值,PHP 将触发通知,这应该会解决这个问题。
  2. 你可以内联整个东西:

    function isNonEmptyStr($var) {
        return is_string($var) && strlen($var) > 0;
    }
    

    这可能会稍微提高一些性能或不提高,但主要是读起来更明智。

除了这些点之外,没有太多需要简化的地方。如果您想准确地检查是字符串并且不为空,那么这就是要做的检查。如果你说你经常使用这个,也许你需要要么接受 PHP 的动态类型特性,要么更多地进行类型处理(要求你确切知道什么时候可以转换成什么),或者您需要更少的数据入口点来进行验证,并且可以更多地依赖您在整个应用中完成的验证。

【讨论】:

  • 如果 $var 是一个数组,这会失败吗?还是我错过了什么?
  • @Mirko 定义“失败”...!?
  • @Mirko - 数组将在 is_string 处返回 false。该函数正确拒绝数组。
【解决方案3】:

要检查传递的变量是否为字符串类型,请使用函数is_string($var)。请看下面的例子:

<?php
    var_dump( is_string('hello') ); // true
    var_dump( is_string('') ); // true
    var_dump( is_string('5') ); // true
    var_dump( is_string('false') ); // true
?>

要检查它是否不为空,可以使用函数isset()见下例:

<?php
    $str = '';
 
    var_dump(isset($str)); // true
?>

阅读更多: How to check if a variable is a String in PHP?

How to check if a variable is undefined in PHP?

【讨论】:

    【解决方案4】:
    function isNonEmptyString($var){
        return !empty($var) && is_string($var);
    }
    

    如果您在字符串已经为空的情况下检查 !empty,它将避免检查 is_string,这将避免 1 次检查。

    【讨论】:

    • 如果他先检查is_string() 并且它不是字符串,他可以避免1 次检查。 :)
    • '0' 被视为empty
    • @deceze 如果传递了“0”,该函数应返回 true
    • @evilReiko 它没有那样做,现在做到了!?
    • @evilReiko 但是这个isNonEmptyString('0') 返回false,违反你的规范!
    【解决方案5】:
    <?php
    
    $var = ' ';
    
    if(!empty($var) && is_string($var)) {
        echo 'true';
    } else {
        echo 'false';
    }
    

    【讨论】:

    • '0' 被视为empty
    • 你是对的,你的问题实际上要糟糕得多。您让任何 非空值 通过!根据此代码,new stdClass 也将被视为“非空字符串”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 2013-12-15
    • 2012-04-13
    • 1970-01-01
    • 2015-11-03
    • 2011-06-18
    • 2014-03-03
    相关资源
    最近更新 更多