【问题标题】:How to get the real type of a value inside string?如何获取字符串中值的真实类型?
【发布时间】:2011-02-11 01:12:23
【问题描述】:

我在 StackOverflow 上搜索有关将字符串转换为实际值的信息,但没有找到。 我需要一个像“gettype”这样的函数来完成上面的结果,但我不能全部完成:s

gettypefromstring("1.234"); //returns (doble)1,234;
gettypefromstring("1234"); //returns (int)1234;
gettypefromstring("a"); //returns (char)a;
gettypefromstring("true"); //returns (bool)true;
gettypefromstring("khtdf"); //returns (string)"khtdf";

谢谢大家:)

【问题讨论】:

    标签: php variables types


    【解决方案1】:

    这是这个已有 9 年历史的函数的更新版本:

    /**
     * Converts a form input request field's type to its proper type after values are received stringified.
     *
     * Function flow:
     *      1. Check if it is an array, if yes, return array
     *      2. Remove unused spaces
     *      3. Check if it is '0', if yes, return 0
     *      4. Check if it is empty, if yes, return blank string
     *      5. Check if it is 'null', if yes, return null
     *      6. Check if it is 'undefined', if yes, return null
     *      7. Check if it is '1', if yes, return 1
     *      8. Check if it is numeric
     *      9. If numeric, this may be a integer or double, must compare this values
     *      10. If string, try parse to bool
     *      11. If not, this is string
     *
     * (c) José Moreira - Microdual (www.microdual.com)
     * With the help of Svisstack (http://stackoverflow.com/users/283564/svisstack)
     *
     * Found at: https://stackoverflow.com/questions/2690654/how-to-get-the-real-type-of-a-value-inside-string
     *
     * @param  string $string
     * @return mixed
     */
    
    function typeCorrected($string) {
        if (gettype($string) === 'array') {
            return (array)$string;
        }
    
        $string = trim($string);
    
        if ($string === '0') { // we must check this before empty because zero is empty
            return 0;
        }
    
        if (empty($string)) {
            return '';
        }
    
        if ($string === 'null') {
            return null;
        }
    
        if ($string === 'undefined') {
            return null;
        }
    
        if ($string === '1') {
            return 1;
        }
    
        if (!preg_match('/[^0-9.]+/', $string)) {
            if(preg_match('/[.]+/', $string)) {
                return (double)$string;
            }else{
                return (int)$string;
            }
        }
    
        if ($string == 'true') {
            return true;
        }
    
        if ($string == 'false') {
            return false;
        }
    
        return (string)$string;
    }
    

    我在 Laravel 中间件中使用它来将由浏览器 JavaScript 的 FormData.append() 字符串化的表单值转换回正确的 PHP 类型:

    public function handle($request, Closure $next)
    {
        $input = $request->all();
    
        foreach($input as $key => $value) {
            $input[$key] = $this->typeCorrected($value);
        }
    
        $request->replace($input);
    
        return $next($request);
    }
    
    1. 要创建它,请在 CLI 中输入 php artisan make:middleware TransformPayloadTypes

    2. 然后粘贴上面的handle函数。

    3. 不要忘记粘贴typeCorrected 函数。我目前建议在您的中间件类中将其设为private function,但我并不声称自己是超级专家。

    您可以想象$request->all() 是一个键/值对数组,它包含所有字符串化的值,因此目标是将它们转换回它们的真实类型。 typeCorrected 函数执行此操作。我已经在应用程序中运行了几个星期了,所以边缘情况可能仍然存在,但在实践中,它正在按预期工作。

    如果你得到了上面的工作,你应该可以在 Axios 中做这样的事情:

    // note: `route()` is from Tightenco Ziggy composer package
    const post = await axios.post(route('admin.examples.create', {
        ...this.example,
        category: undefined,
        category_id: this.example.category.id,
    }));
    

    然后,在您的 Laravel 控制器中,您可以执行 \Log::debug($request->all()); 并看到如下内容:

    [2020-10-12 17:52:43] local.DEBUG: array (
      'status' => 1,
      'slug' => 'asdf',
      'name' => 'asdf',
      'category_id' => 2,
    ) 
    

    关键事实是您看到的是'status' => 1, 而不是'status' => '1',

    所有这些都将允许您通过 Axios 提交 JSON 负载,并在实际负载类型发生变化时在您的 FormRequest 类和控制器中接收非嵌套值。我发现其他解决方案太复杂了。上述解决方案允许您轻松地从纯 JavaScript 提交平面 JSON 有效负载(到目前为止,哈哈)。

    【讨论】:

    • 这是一个非常有帮助的答案。
    【解决方案2】:

    Svisstack 1+! ;)

    如果有人想要,这里是函数:

    function gettype_fromstring($string){
        //  (c) José Moreira - Microdual (www.microdual.com)
        return gettype(getcorrectvariable($string));
    }
    function getcorrectvariable($string){
        //  (c) José Moreira - Microdual (www.microdual.com)
        //      With the help of Svisstack (http://stackoverflow.com/users/283564/svisstack)
    
        /* FUNCTION FLOW */
        // *1. Remove unused spaces
        // *2. Check if it is empty, if yes, return blank string
        // *3. Check if it is numeric
        // *4. If numeric, this may be a integer or double, must compare this values.
        // *5. If string, try parse to bool.
        // *6. If not, this is string.
    
        $string=trim($string);
        if(empty($string)) return "";
        if(!preg_match("/[^0-9.]+/",$string)){
            if(preg_match("/[.]+/",$string)){
                return (double)$string;
            }else{
                return (int)$string;
            }
        }
        if($string=="true") return true;
        if($string=="false") return false;
        return (string)$string;
    }
    

    我用这个函数知道数字 X 是否是 Y 的倍数。

    例子:

    $number=6;
    $multipleof=2;
    if(gettype($number/$multipleof)=="integer") echo "The number ".$number." is multiple of ".$multipleoff.".";
    

    但我工作的框架总是将输入变量作为字符串返回。

    【讨论】:

    • 你有一些额外的代码。 empty 已经测试了一个空字符串。你为什么使用|| $striing == ""?此外,您正在将字符串转换为字符串。 PHP 知道"" 是一个字符串。该行可以重写为:if (empty($string)) return ""。另外,return (bool)true/false 没有意义。 truefalse 已经是布尔值;他们不需要被铸造。
    【解决方案3】:

    你必须尝试按指定的顺序转换它:

    1. 检查是双重的
    2. 如果是double,这可能是一个整数,您必须转换和比较这个值。
    3. 如果不是,如果长度为 == 1,则为 char。
    4. 如果不是,这是字符串。
    5. 如果是字符串,尝试解析为布尔值。

    你不能使用gettype,因为你可能会得到字符串类型的十进制字符串。

    【讨论】:

    • 谢谢,我会试试的。是的,我知道,这就是我想要这个功能的原因;)
    • 问题,如果字符串有“12ab3”?它是字符串吗?我怎么知道字符串是否有字母数字字符?
    • "12ab3" 不是 int,因为有一个字母数字,然后算法不会从中检查双精度,它们的长度大于 1,那么这是字符串,并且无法将其解析为布尔值。结果是字符串,实际结果是字符串,因为“12ab3”不是有效数字。
    • 我已在此处添加该功能作为答案,并感谢您;)
    猜你喜欢
    • 2017-05-21
    • 1970-01-01
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    相关资源
    最近更新 更多