1

key=>value ペアとしてユーザー入力 ($atts) の配列があります。一部の値は、次のように配列式として記述できます。

'setting' => 'array(50,25)'

その場合、その文字列に含まれる配列式を実際の配列に変換したいと考えています。したがって、出力は次のようになります。

$atts = array(
'setting' => array(50,25),
'another' => 'not written as an array expression'
)

論理的に書くと、コードは次のようになります。

配列 $atts 内の各 key=>value ペアに対して...値が配列式としてフォーマットされた文字列である場合...その値を配列に分解します。

PHPでこれを書く方法を知っている人はいますか?

4

4 に答える 4

2

トークナイザーを使用します。

function stringToArray($str) {
    $array = array();
    $toks = token_get_all("<?php $str");

    if ($toks[1][0] != T_ARRAY || $toks[2] != '(' || end($toks) != ')')
        return null;

    for($i=3; $i<count($toks)-1; $i+=2) {
        if (count($toks[$i]) != 3)
            return null;

        if ($toks[$i][0] == T_WHITESPACE) {
            $i--;
            continue;
        }

        if ($toks[$i][0] == T_VARIABLE || $toks[$i][0] == T_STRING)
            return null;

        $value = $toks[$i][1];
        if ($toks[$i][0] == T_CONSTANT_ENCAPSED_STRING)
            $value = substr($value, 1, strlen($value) - 2);

        $array[] = $value;

        if ($toks[$i + 1] != ',' && $toks[$i + 1] != ')' && $toks[$i + 1][0] != T_WHITESPACE)
            return null;
    }

    return $array;
}

上記はリテラルに対してのみ機能します。変数、定数、式、ネストされた配列、または不正な形式の配列宣言を渡すと、以下が返されnullます。

stringToArray('array(1,2)');              // works
stringToArray('array(1,2.4)');            // works
stringToArray('array("foo",2)');          // works
stringToArray('array(\'hello\',2)');      // works
stringToArray('array()');                 // works
stringToArray('array(1,2 + 3)');          // returns null
stringToArray('array(1,2 + 3)');          // returns null
stringToArray('array("foo"."bar")');      // returns null
stringToArray('array(array("hello"))');   // returns null
stringToArray('array($a,$b)');            // returns null
stringToArray('array(new bar)');          // returns null
stringToArray('array(SOME_CONST)');       // returns null
stringToArray('hello');                   // returns null

次を使用して、文字列が配列式であるかどうかを確認することもできます。

function isArrayExpression($str) {
    $toks = token_get_all("<?php $str");
    return (
        $toks[1][0] == T_ARRAY &&
        $toks[2] == '(' &&
        end($toks) == ')'
    );
}

isArrayExpression('array(1,2,3)');         // true
isArrayExpression('array is cool');        // false
isArrayExpression('array(!!!!');           // false

必要に応じていつでも微調整できます。お役に立てれば。

于 2012-06-29T19:18:00.160 に答える
0

投稿のコメントで示唆されているように、 eval() はあなたが探していることを行います。ただし、そもそも配列を文字列として格納するのは現実的ではありません。データの移植性を高めたい場合は、json_encode()またはserialize () を使用することをお勧めします

于 2012-06-29T19:01:29.080 に答える
0

eval を使用することもできますが、使用しないことを強くお勧めします。代わりに、設定を処理するためのより良い方法で設計を再考してみてください。あなたの例では、保存する代わりに

'setting' => 'array(50,25)'

次のようなことができますか

'setting' => array('type'=>'array', 'value'=>'50, 25')

次に、設定をロードするときにできること

switch($type)
case 'array'
  $val = explode(', ', $value)

または似たようなもの

しかし、他の人が示唆したように、シリアル化を使用して設定を保存しようとします

于 2012-06-29T18:57:45.093 に答える