यह निर्धारित करने का सबसे अच्छा तरीका है कि क्या एक स्ट्रिंग serialize()
फ़ंक्शन का परिणाम है या नहीं ?
यह निर्धारित करने का सबसे अच्छा तरीका है कि क्या एक स्ट्रिंग serialize()
फ़ंक्शन का परिणाम है या नहीं ?
जवाबों:
मैं कहता हूँ, unserialize
इसे करने की कोशिश; ;-)
मैनुअल का हवाला देते हुए:
यदि उत्तीर्ण स्ट्रिंग अपरिहार्य नहीं है, तो FALSE लौटा दिया जाता है और E_NOTICE जारी किया जाता है।
तो, आप अगर वापसी मान है की जाँच करने के लिए है false
या नहीं (के साथ ===
या !==
, सुनिश्चित करें के साथ किसी भी समस्या है करने के लिए नहीं होने के लिए 0
या null
या कुछ भी है कि करने के लिए बराबर होती है false
, मैं कहता हूँ चाहते हैं) ।
बस नोटिस से सावधान रहें: आप @ ऑपरेटर का उपयोग करना चाहते हैं / कर सकते हैं ।
उदाहरण के लिए :
$str = 'hjkl';
$data = @unserialize($str);
if ($data !== false) {
echo "ok";
} else {
echo "not ok";
}
आपको मिलेगा:
not ok
संपादित करें: ओह, और जैसे @Peter ने कहा (उसके लिए धन्यवाद!), आप मुसीबत में दौड़ सकते हैं यदि आप एक बूलियन झूठी के प्रतिनिधित्व को अनसुना करने की कोशिश कर रहे हैं :-(
इसलिए, यह जांचना कि आपका क्रमबद्ध स्ट्रिंग " b:0;
" के बराबर नहीं है, सहायक हो सकता है; कुछ इस तरह करना चाहिए चाल, मुझे लगता है:
$data = @unserialize($str);
if ($str === 'b:0;' || $data !== false) {
echo "ok";
} else {
echo "not ok";
}
परीक्षण करने से पहले उस विशेष मामले का परीक्षण करने का प्रयास एक अनुकूलन होगा - लेकिन शायद यह उपयोगी नहीं है, यदि आपके पास अक्सर गलत धारावाहिक मूल्य नहीं है।
मैंने यह कोड नहीं लिखा है, यह वास्तव में वर्डप्रेस से है। सोचा था कि मैं इसे किसी के लिए भी शामिल करूंगा, यह ओवरकिल हो सकता है लेकिन यह काम करता है :)
<?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;
}
^([adObis]:|N;)
यदि $ स्ट्रिंग एक सीरियलाइज्ड false
वैल्यू है, तो $string = 'b:0;'
SoN9ne का फंक्शन रिटर्न देता है false
, यह गलत है
तो समारोह होगा
/**
* Check if a string is serialized
*
* @param string $string
*
* @return bool
*/
function is_serialized_string($string)
{
return ($string == 'b:0;' || @unserialize($string) !== false);
}
In case the passed string is not unserializeable, FALSE is returned and E_NOTICE is issued.
हम E_NOTICE त्रुटि को नहीं पकड़ सकते, क्योंकि यह एक फेंक दिया अपवाद नहीं है।
पास्कल मार्टिन के शानदार जवाब के बावजूद, मैं उत्सुक था कि क्या आप इस तरह से संपर्क कर सकते हैं, इसलिए मैंने मानसिक अभ्यास के रूप में ऐसा किया
<?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 काम करता है तो आपके पास पंजीकृत त्रुटि हैंडलर होने पर यह टूट जाएगा ।
$a
और डिसेरिएलाइज़िंग के बीच त्रुटि की जाँच नहीं करते हैं $b
, जो व्यावहारिक अनुप्रयोग डिज़ाइन नहीं है।
एक समारोह के लिए निर्माण
function isSerialized($value)
{
return preg_match('^([adObis]:|N;)^', $value);
}
a:
(या b:
आदि) $ मूल्य के अंदर कहीं मौजूद है, शुरुआत में नहीं। और ^
यहाँ एक स्ट्रिंग की शुरुआत का मतलब नहीं है। यह पूरी तरह से भ्रामक है।
वर्डप्रेस समाधान है: (विवरण यहाँ है)
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;
}
/**
* 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));
}
?>
मैं इसे इस तरह से करना पसंद करता हूं:
if (is_array(unserialize($serialized_string))):