【问题标题】:check if item can be converted to string?检查项目是否可以转换为字符串?
【发布时间】:2011-07-26 16:22:33
【问题描述】:

我正在写一个调试方法。

我拥有的是

if(is_xxx($item)){
 //echo output info for type
}

最后我想做的是

if(can_be_string($item))
echo $item;

有can_be_string类型的函数吗?

【问题讨论】:

  • @Hailwood 我知道的唯一不能成为字符串的项目是没有__toString() 方法的对象。你在哪里遇到问题?
  • 某事物是否可以是字符串的决定因素是什么?我不明白这个问题。
  • 我也不相信可以将资源转换为字符串 - 不仅仅是对象(除非它们有 __toString),但我认为这些是唯一的例外
  • 是的,这个函数无法控制插入的内容。因此有人可以传入例如数据库资源,但无法将其转换为字符串。
  • 如果您正在回显而不是 var_dumping,请为 is_null() 添加一个陷阱...否则您将看不到回显的内容

标签: php function tostring


【解决方案1】:

好的,已编辑,包含Michiel Pater 的建议(现在谁的答案已经消失)和@eisberg 的建议。无论如何,settype 将返回带有对象的 true,看起来。

if(
    ( !is_array( $item ) ) &&
    ( ( !is_object( $item ) && settype( $item, 'string' ) !== false ) ||
    ( is_object( $item ) && method_exists( $item, '__toString' ) ) )
)
{
    echo $item;
}

【讨论】:

  • Integers, double, float, ... 也可以转换。数组也是,但没有提供任何有用的信息:-)
  • @eisberg:呃,你当然是对的!让我检查一下我自己的一些项目是否存在这个错误。哈哈。
  • @eisberg:那你觉得怎么样?顺便提早打个电话!
  • 我会说如果我真的需要手动调试任何东西,而不是var_dump(),var_export(),print_r(),...我会switch/case@987654331 @.
  • 我很惊讶settype()没有出现在me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design中
【解决方案2】:

为了完成……

http://www.php.net/is_scalar,自 PHP 4 起可用;一言不发.. :)

【讨论】:

  • 某些对象可以转换为字符串。也就是说,如果他们实现了神奇的方法__toString()。注释还说由于某种原因它不考虑空值标量。最重要的是,在资源上使用这个函数似乎不可靠。
【解决方案3】:

怎么样

function can_be_string($var) {
    return $var === null || is_scalar($var) || (is_object($var) && method_exists($var, '__toString'));
}

从 PHP 8 开始,您可以将第三个条件替换为 $var instanceof Stringable

【讨论】:

  • 如果传递一个带有许可__call 函数的对象,这将返回不正确的结果,请参阅:3v4l.org/4ttLv。使用method_exists 而不是is_callable
  • 另外,使用method_exists 而不是is_callable 也没有缺点,因为__toString 必须是公开的
【解决方案4】:

快速而肮脏的测试实现:

function canBeString($value)
{
    if (is_object($value) and method_exists($value, '__toString')) return true;

    if (is_null($value)) return true;

    return is_scalar($value);
}

class MyClass
{    
}

$object = new MyClass();
var_dump(canBeString($object)); // bool(false)

class MyClassWithToString
{
    public function __toString()
    {
        return 'foo';
    }
}

$objectWithToString = new MyClassWithToString();
var_dump(canBeString($objectWithToString)); // bool(true)

var_dump(canBeString(1)); // bool(true)
echo (string)1 . "\n";

var_dump(canBeString(false)); // bool(true)
echo (string)true . "\n";

var_dump(canBeString(1.0)); // bool(true)
echo (string)1.0 . "\n";

var_dump(canBeString(null)); // bool(false)
var_dump((string)null); // string(0) ""

【讨论】:

  • 我喜欢这个。我将与array_filter 一起使用它来删除不可字符串化的项目。
【解决方案5】:

这是我能找到的最短路径:

/**
 * Determine if we can cast a value to a string.
 *
 * @param mixed $v
 *
 * @return bool
 */
function can_be_string($v): bool
{
    return method_exists($v, '__toString') || $v === null || is_scalar($v);
}

【讨论】:

    【解决方案6】:

    这个决定怎么样?

    function canBeString ($value) {
        try {
            $value = (string) $value;
        } catch (\ErrorException $exception) {
            return false;
        }
    
        return true;
    }
    

    【讨论】:

    • 我经常为这种情况选择这种类型的解决方案并相应地投票,尽管在测试它时,这是不行的,因为它会抛出一个“可捕获的致命错误”(至少在 PHP 5 中) ),从技术上讲,由于我无法理解的原因,这在传统意义上是不可“捕获”的 - 请参阅 stackoverflow.com/questions/2468487/…。
    【解决方案7】:

    如果 is_string() 对你没有帮助,那么我只能提出一些想法:

    • 如果变量不是字符串,则捕获 strlen() 或另一个引发错误的函数
    • 如果不为 NULL,则使用 to_string() 并检查字符串是否仅包含数字字符。如果不是(并且变量/对象是一个简单的变量),您可以假设一些事情

    【讨论】:

    • 我喜欢使用if (strlen()) { // It's save to use where you expect a string. }
    【解决方案8】:

    很简单:

    function can_be_string($var)
    {
        return method_exists($var, '__toString') || (is_scalar($var) && !is_null($var));
    }
    

    代码已经过测试。 如果$var 不是对象,则method_exists() 函数返回false,因此无需进行此验证。

    【讨论】:

      【解决方案9】:

      我认为没有一个答案是令人满意的。

      最简单的实现:

      function can_be_string($value) {
          return (!is_object($value) && !is_array($value))
              || method_exists($value, '__toString');
      }
      
      class IsString {
          public function __toString() {
              return 'hello';
          }
      }
      
      var_dump(
          can_be_string(null), // true
          can_be_string(123), // true
          can_be_string(12.3), // true
          can_be_string('hello'), // true
          can_be_string(new IsString), // true
          can_be_string(new stdClass), // false
          can_be_string([1, 2, 3]) // false
      );
      

      【讨论】:

      • 这不考虑数字。它们完全可以作为字符串回显。
      • @MagnusEriksson 是的,没有正确阅读主题,已更新。
      【解决方案10】:

      使用print_r() 和var_dump() 函数,您可以打印出任何变量的内容。

      如果你不喜欢上述函数的输出,这里有很多类型检查函数http://www.php.net/manual/en/ref.var.php

      【讨论】:

      • 当它没有回答问题时为什么会被接受?
      猜你喜欢
      • 2022-10-15
      • 1970-01-01
      • 2016-10-07
      • 1970-01-01
      • 2010-12-28
      • 2022-09-30
      • 2010-10-18
      • 2012-08-16
      • 2017-09-12
      相关资源
      最近更新 更多