如何在字符串中获取值的实际类型?

时间:2010-04-22 12:19:01

标签: php variables types

我在这里搜索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";

感谢所有人:)

3 个答案:

答案 0 :(得分:6)

1+为Svisstack! ;)

以下是有人想要的功能:

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.".";

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

答案 1 :(得分:5)

您必须尝试按指定的顺序进行转换:

  1. 支票是双
  2. 如果是double,这可能是整数,您必须转换并比较这些值。
  3. 如果不是,如果长度为== 1,则为char。
  4. 如果没有,这是字符串。
  5. 如果是字符串,请尝试解析bool。
  6. 您不能使用gettype,因为您可能会在字符串中获得十进制字符串的字符串类型。

答案 2 :(得分: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负载(到目前为止,哈哈)。