文字列がserialize()関数の結果/出力であるかどうかを判断する最良の方法は何ですか?
unserialize
it ;-)にしてみてください
マニュアルの引用:
渡された文字列がシリアライズ可能でない場合、FALSEが返され、E_NOTICEが発行されます。
したがって、戻り値がfalse
であるかどうかを確認する必要があります(===
または!==
で、0
またはnull
、またはfalse
に等しいものに問題がないことを確認するために、 d say).
通知に注意してください: @ operator を使用する必要がある場合があります。
例えば :
$str = 'hjkl';
$data = @unserialize($str);
if ($data !== false) {
echo "ok";
} else {
echo "not ok";
}
あなたを取得します:
not ok
[。
したがって、シリアル化された文字列が「b:0;
」と等しくないことを確認することも役立ちます。このような何かがトリックを行うはずです、私は思う:
$data = @unserialize($str);
if ($str === 'b:0;' || $data !== false) {
echo "ok";
} else {
echo "not ok";
}
シリアル化を解除する前にその特殊なケースをテストすることは最適化になりますが、誤ったシリアル化された値が頻繁にない場合は、おそらくそれほど有用ではありません。
私はこのコードを書きませんでした。実際はWordPressからです。私は興味のある人のためにそれを含めると思った、それはやり過ぎかもしれませんが、それは動作します:)
<?php
function is_serialized( $data ) {
// if it isn't a string, it isn't serialized
if ( !is_string( $data ) )
return false;
$data = trim( $data );
if ( 'N;' == $data )
return true;
if ( !preg_match( '/^([adObis]):/', $data, $badions ) )
return false;
switch ( $badions[1] ) {
case 'a' :
case 'O' :
case 's' :
if ( preg_match( "/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data ) )
return true;
break;
case 'b' :
case 'i' :
case 'd' :
if ( preg_match( "/^{$badions[1]}:[0-9.E-]+;\$/", $data ) )
return true;
break;
}
return false;
}
Pascal MARTINの応答の最適化
/**
* Check if a string is serialized
* @param string $string
*/
public static function is_serial($string) {
return (@unserialize($string) !== false);
}
$ stringがシリアル化されたfalse
値、つまり$string = 'b:0;'
SoN9neの関数が返す場合false
、間違っています
そのため、関数は
/**
* Check if a string is serialized
* @param string $string
*/
function is_serial($string) {
return ($string == 'b:0;' || @unserialize($string) !== false);
}
パスカル・マーティンの優れた答えにもかかわらず、この別の方法でアプローチできるかどうか興味があったので、メンタルエクササイズとしてこれを行いました
<?php
ini_set( 'display_errors', 1 );
ini_set( 'track_errors', 1 );
error_reporting( E_ALL );
$valueToUnserialize = serialize( false );
//$valueToUnserialize = "a"; # uncomment this for another test
$unserialized = @unserialize( $valueToUnserialize );
if ( FALSE === $unserialized && isset( $php_errormsg ) && strpos( $php_errormsg, 'unserialize' ) !== FALSE )
{
echo 'Value could not be unserialized<br>';
echo $valueToUnserialize;
} else {
echo 'Value was unserialized!<br>';
var_dump( $unserialized );
}
そして、実際に動作します。唯一の注意点は、 $ php_errormsgが機能する の方法が原因で、登録済みのエラーハンドラーがあると壊れる可能性があることです。
$data = @unserialize($str);
if($data !== false || $str === 'b:0;')
echo 'ok';
else
echo "not ok";
serialize(false)
のケースを正しく処理します。 :)
WordPressソリューションがあります: (詳細はこちら)
function is_serialized($data, $strict = true)
{
// if it isn't a string, it isn't serialized.
if (!is_string($data)) {
return false;
}
$data = trim($data);
if ('N;' == $data) {
return true;
}
if (strlen($data) < 4) {
return false;
}
if (':' !== $data[1]) {
return false;
}
if ($strict) {
$lastc = substr($data, -1);
if (';' !== $lastc && '}' !== $lastc) {
return false;
}
} else {
$semicolon = strpos($data, ';');
$brace = strpos($data, '}');
// Either ; or } must exist.
if (false === $semicolon && false === $brace)
return false;
// But neither must be in the first X characters.
if (false !== $semicolon && $semicolon < 3)
return false;
if (false !== $brace && $brace < 4)
return false;
}
$token = $data[0];
switch ($token) {
case 's' :
if ($strict) {
if ('"' !== substr($data, -2, 1)) {
return false;
}
} elseif (false === strpos($data, '"')) {
return false;
}
// or else fall through
case 'a' :
case 'O' :
return (bool)preg_match("/^{$token}:[0-9]+:/s", $data);
case 'b' :
case 'i' :
case 'd' :
$end = $strict ? '$' : '';
return (bool)preg_match("/^{$token}:[0-9.E-]+;$end/", $data);
}
return false;
}
関数に組み込む
function isSerialized($value)
{
return preg_match('^([adObis]:|N;)^', $value);
}
/**
* some people will look down on this little puppy
*/
function isSerialized($s){
if(
stristr($s, '{' ) != false &&
stristr($s, '}' ) != false &&
stristr($s, ';' ) != false &&
stristr($s, ':' ) != false
){
return true;
}else{
return false;
}
}
これは私のためにうまくいきます
<?php
function is_serialized($data){
return (is_string($data) && preg_match("#^((N;)|((a|O|s):[0-9]+:.*[;}])|((b|i|d):[0-9.E-]+;))$#um", $data));
}
?>