问题 如何在PHP中检查它是否是正常的字符串或二进制字符串? [重复]


可能重复:
如何在PHP中检查文件是ASCII还是二进制 

我有一个函数,它接受图像文件的名称(即普通字符串),或者它可以直接接受图像字节作为二进制字符串。由返回 file_get_contents

我如何区分这两者?


1334
2017-08-22 10:33


起源

我认为这是同一个问题: stackoverflow.com/questions/632685/... - Rijk
这个问题的答案如下: stackoverflow.com/questions/632685/... - Matthew Caruana Galizia
这“完全重复”怎么样?打开文件并检查MIME。这里我有二进制数据作为字符串。我如何检查其MIME? - AppleGrew
这不重复。 - OZ_


答案:


您可以检查输入是否仅由可打印字符组成。你可以用ctype_print()来做到这一点:

if (ctype_print($filename)) { // this is most probably not an image

您还可以检查参数是否为有效图像,或者是否存在具有该名称的文件。

但是,创建两个单独的函数会更好,更可靠:

  • 一个load_image_from_string(),它总是将图像作为参数
  • 和一个load_image_from_file(),它将读取文件并调用load_image_from_string()

15
2017-08-22 10:39



此外,你可以尝试有根据的猜测 - 如果字符串的长度超过1k字节,它很可能是图像。 - Maxim Krizhanovsky
魔术代码=难以调试。 - hakre
@Darhazer:但请在加载器功能区分旁边添加第三个函数。 - hakre
@Darhazer好主意。 - AppleGrew
@AppleGrew:让构造函数变得愚蠢,不要为它们添加太多代码。而是创建两个可以具有相同父类的对象。一个期望文件名字符串,另一个期望二进制数据字符串或类似。或者创建一个小心的工厂方法。 - hakre


在PHP中,所有字符串都是二进制的(截至当前的PHP 5.3),因此无法区分。因此,您无法区分参数是二进制数据还是技术上的文件名(字符串或字符串)。

但是,您可以创建第二个函数来处理重新使用处理图像数据的函数的文件。因此函数的名称清楚地表明了它所期望的参数。


如果您需要根据作为参数传递给函数的类型来决定,则必须向数据添加上下文。一种方法是制作某种类型的参数:

abstract class TypedString
{
    private $string;
    public final function __construct($string)
    {
        $this->string = (string) $string;
    }
    public final function __toString()
    {
        return $this->string;
    }
}

class FilenameString extends TypedString {}

class ImageDataString extends TypedString {}


function my_image_load(TypedString $string)
{
    if ($string instanceof FilenameString)
    {
        $image = my_image_load_file($string);
    }
    elseif ($string instanceof ImageDataString)
    {
        $image = my_image_load_data($string);
    }
    else
    {
         throw new Exception('Invalid Input');
    }
    # continue loading the image if needed
}
function my_image_load_file($filename)
{
    # load the image from file and return it
}
function my_image_load_data($data)
{
    # load the image from data and return it
}

但是我认为更容易处理正确的命名函数,否则如果你使用类进行类型区分,你就会使事情变得不必要复杂 只要


1
2017-08-22 10:41



hakre,你的答案听起来像“不可能判断数字是10还是1000,因为它们都是数字“。虽然我同意”字符串是一个字符串“,在这种情况下,两个字符串都具有不同的性质 - 一种类型的字符串可能只包含在文件名中有效的字符,另一种字符串可能包含其他字符,并且不像文件名那样”看起来“。 - binaryLV
本质上,字符串的类型没有区别。但是,无论挑选条件如何,您希望通过评论获得什么?告诉我一个字符串的内容可以有所不同?这对我来说不是新闻。这就是我们使用字符串变量来存储不同值的原因。但通常我们在数据旁边使用上下文。并且上下文应该清楚,否则你会遇到复杂性问题迟早会说:废话会停止工作。 - hakre