একটি স্ট্রিং সিরিয়ালযুক্ত কিনা তা পরীক্ষা করে দেখুন?


উত্তর:


191

আমি বলব, unserializeএটি চেষ্টা করে দেখুন ;-)

ম্যানুয়ালটি উদ্ধৃত করা হচ্ছে:

যদি পাস করা স্ট্রিংটি নিরীক্ষণযোগ্য না হয় তবে FALSE ফিরে আসে এবং E_NOTICE জারি করা হয়।

সুতরাং, আপনি যদি ফেরত মান কিনা চেক করতে হবে falseবা না (সঙ্গে ===বা !==, নিশ্চিত করুন না হতে দিয়ে কোনো সমস্যা আছে 0বা nullকিছু যে সমান false, আমি বলতে চাই)

শুধু বিজ্ঞপ্তি থেকে সাবধান: আপনার @ অপারেটরটি ব্যবহার করতে / প্রয়োজন হতে পারে ।

এই ক্ষেত্রে :

$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";
}

আনসিরিয়ালাইজ করার চেষ্টা করার আগে সেই বিশেষ কেসটি পরীক্ষা করা একটি অপ্টিমাইজেশন হতে পারে - তবে সম্ভবত সেই দরকারী নয়, যদি আপনার প্রায়শই কোনও মিথ্যা সিরিয়ালাইজড মান না থাকে।


20
তবে কি যদি অপ্রচালিত মানটি মিথ্যা মান সহ একটি বুলিয়ান হয়?
পিটার

1
@ পিটার: দুর্দান্ত মন্তব্য; আমি আমার উত্তরটি সেই মামলার সাথে মোকাবিলার প্রস্তাব দিয়ে সম্পাদনা করেছি; ধন্যবাদ!
পাস্কাল মার্টিন

ধন্যবাদ। :) আমি ধরে নিয়েছি এটি সম্ভবত উত্তর হতে চলেছে .. কেবল আমার কাছে মনে হয়েছে এটির প্রক্রিয়া করার চেষ্টা করার জন্য পার্সারকে বলপূর্বক বাধ্য করার আগে এটির সিরিয়ালযুক্ত কিনা তা অনুসন্ধান করার একটি উপায় থাকা উচিত।
ডাং

1
এই পদ্ধতির কি ডেটার বড় অংশের সাথে পারফরম্যান্সে কোনও যুক্তিসঙ্গত প্রভাব আছে?
পাই 6 কে

2
গুরুত্বপূর্ণ: কখনও কখনও কাঁচা ব্যবহারকারীর ডেটা আনসিরিয়ালাইজ করবেন না কারণ এটি আক্রমণকারী ভেক্টর হিসাবে ব্যবহার করা যেতে পারে। OWASP: PHP_Object_Inication
আর্টবিআইটি

56

আমি এই কোডটি লিখিনি, এটি আসলে ওয়ার্ডপ্রেস থেকে। ভেবেছিলাম আমি আগ্রহী যে কারও জন্য এটি অন্তর্ভুক্ত করব, এটি ওভারকিল হতে পারে তবে এটি কার্যকর হয় :)

<?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;
}

1
আমার প্রাথমিকভাবে একটি প্রাথমিক সনাক্তকরণের জন্য একটি রেইজেক্সের দরকার ছিল, আমি ^([adObis]:|N;)
এইটি

5
বর্তমান ওয়ার্ডপ্রেস সংস্করণটি কিছুটা পরিশীলিত: কোডেক্স.ওয়ার্ডপ্রেস.আর.
ফাংশন_প্রকাশ

3
ক্রেডিট দেওয়ার জন্য +1। আমি জানতাম না ওয়ার্ডপ্রেসটির এই বিল্ট-ইন ছিল। ধারণার জন্য ধন্যবাদ - আমি এখন এগিয়ে যাব এবং ওয়ার্ডপ্রেস কোর থেকে দরকারী ফাংশনগুলির একটি সংরক্ষণাগার তৈরি করব।
অমল মুরালি

ওয়ার্ডপ্রেস ফাংশন রেফারেন্স থেকে সর্বশেষ URL টি: developer.wordpress.org/reference/functions/is_serialized
সেডরিক Françoys

18

পাস্কাল মার্টিনের প্রতিক্রিয়া অনুকূল করা

/**
 * Check if a string is serialized
 * @param string $string
 */
public static function is_serial($string) {
    return (@unserialize($string) !== false);
}

16

যদি স্ট্রিংটি সিরিয়ালযুক্ত 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);
}

2
এই পরীক্ষার ক্রম অদলবদল আরও কার্যকর হবে efficient
আর্টফুলবোট 9

@ (অপারেটরে) নিরুৎসাহিত করা উচিত। পরিবর্তে ক্যাচ ব্লক ব্যবহার করুন।
ফ্রান্সিসকো লুজ

Php.net/manual/en/function.unserialize.php ম্যানুয়াল থেকে @ ফ্রেঞ্চিসকোলুজ In case the passed string is not unserializeable, FALSE is returned and E_NOTICE is issued. আমরা E_NOTICE ত্রুটি ধরতে পারি না কারণ এটি কোনও ছোঁড়া ব্যতিক্রম নয়।
হাজেম নূর

@ হ্যাজেমনূর আমি পিএইচপি 7 দিয়ে এটি পরীক্ষা করেছি এবং এটি ধরা পড়ে না। এছাড়াও, পিএইচপি in-তে, এমন ক্যাচ রয়েছে (able থ্রোয়েবল) ই) যা হুডের নীচে ভুল হয়ে যায় এমন সমস্ত কিছু আটকায়।
ফ্রান্সিসকো লুজ

@ ফ্রেঞ্চিসক্লোজ কীভাবে আপনি পিএইচপি 7-তে E_Notice- কে ধরেন?
user427969

13

পাস্কাল মার্টিনের দুর্দান্ত উত্তর সত্ত্বেও, আপনি যদি অন্য কোনও উপায়ে যেতে পারতেন তবে আমি আগ্রহী ছিলাম, তাই আমি এটি কেবল একটি মানসিক অনুশীলন হিসাবে করেছি

<?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 );
}

এবং এটি আসলে কাজ করে। কেবলমাত্র সতর্কতা হ'ল it php_errormsg কীভাবে কাজ করে তার কারণে আপনার যদি একটি নিবন্ধিত ত্রুটি হ্যান্ডলার থাকে তবে এটি সম্ভবত ভেঙে যায় ।


1
+1: এটি মজাদার, আমাকে স্বীকার করতে হবে - এটি সম্পর্কে ভাবেননি! এবং এটিকে ব্যর্থ করার উপায়ও আমি খুঁজে পাই না ice চমৎকার কাজ! এবং আমার উত্তরের মন্তব্যের জন্য ধন্যবাদ: এটি না থাকলে আমি সম্ভবত এই উত্তরটি দেখতে পেতাম না।
পাস্কাল মার্টিন 21

$ ক = 'ব্লে'; $ বি = 'বি: 0;'; এটি দিয়ে se a এর পরে $ বি unserialize করার চেষ্টা করুন, both বি না করা উচিত উভয়ই ব্যর্থ হবে।
বারদিয়ার

ঠিক আগে যদি কোনও ব্যর্থতা ঘটে থাকে তবে নয়। কারণ $ php_errormsg এখনও এর আগে থেকে সিরিয়ালাইজেশন ত্রুটিটি ধারণ করে এবং একবার আপনি মিথ্যা নির্মোচন করলে তা ব্যর্থ হবে।
বারদিয়ার

হ্যাঁ, তবে কেবলমাত্র যদি আপনি ডিসরিওলাইজিং $aএবং ডিসিরিয়ালাইজিংয়ের মধ্যে ত্রুটি-চেক না করেন $b, যা ব্যবহারিক প্রয়োগের নকশা নয়।
পিটার বেইলি

11
$data = @unserialize($str);
if($data !== false || $str === 'b:0;')
    echo 'ok';
else
    echo "not ok";

সঠিকভাবে কেস পরিচালনা করে serialize(false)। :)


3

একটি ফাংশন অন্তর্নির্মিত

function isSerialized($value)
{
   return preg_match('^([adObis]:|N;)^', $value);
}

1
এই রেজেক্স বিপজ্জনক, এটি ইতিবাচক প্রত্যাবর্তন করছে যখন a:(বা b:ইত্যাদি) কোথাও $ মানের ভিতরে উপস্থিত হয়, শুরুতে নয়। এবং ^এখানে একটি স্ট্রিং শুরু মানে না। এটি সম্পূর্ণ বিভ্রান্তিকর।
ডেনিস চেমেল

3

ওয়ার্ডপ্রেস সমাধান আছে: (বিস্তারিত এখানে)

    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;
    }

2
/**
 * 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;
}

}

5
ভাল, এটি অনেক JSON স্ট্রিংয়ের ক্ষেত্রেও সত্য দেবে, তাই না? সুতরাং স্ট্রিং আন / সিরিয়ালাইজড করা যায় কিনা তা নির্ধারণ করা নির্ভরযোগ্য নয়।
গর্ডন

সত্য হতে পারে, তবে বিকল্পটি যদি সিরিয়ালাইজড হয় বা কেবল সরল পাঠ্য হিসাবে এটি আমার কাছে ছিল তবে এটি কবজির মতো কাজ করে।
বিজেআরএন 3

1
@ Björn3 "ভাল এই নির্দিষ্ট ক্ষেত্রে এটি আমার জন্য কাজ করে" কোডিংয়ের সময় খুব খারাপ মানসিকতা। এমন অনেক বিকাশকারী আছেন যারা অলস বা এই জাতীয়ভাবে এগিয়ে যাওয়ার চিন্তাভাবনা করেন না এবং পরে যখন এই বিকাশকারীদের তাদের কোড নিয়ে কাজ করতে হয় বা কোনও কিছু পরিবর্তনের চেষ্টা করতে হয় এবং হঠাৎ কিছুই ঠিকমতো কাজ করে না তখন এটি একটি দুঃস্বপ্ন দেখা দেয়।
ব্যাডহর্সি

সম্পূর্ণরূপে কঠিন কোড তৈরি করা (যদি তা এমনকি সম্ভব ছিল) সর্বদা লক্ষ্য বা সর্বোত্তম অনুশীলন নয়। যখন এটি একটি সময় শেষ হয় না। প্রোগ্রামারদের দৃষ্টিকোণ থেকে এটি কেবল সত্য। বাস্তব জীবনে এমন অনেকগুলি পরিস্থিতি রয়েছে যেখানে দ্রুত এবং নোংরা হ'ল পছন্দসই উপায়।
বিজেআরএন 3

1

এটি আমার পক্ষে ভাল কাজ করে

<?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));
    }

?>

প্রদত্ত স্ট্রিংটি সিরিয়ালাইজড স্ট্রিং কিনা তা দয়া করে মনে রাখবেন - এটি আসলে সেই স্ট্রিংয়ের বৈধতা পরীক্ষা করবে না।
15

-2

আমি সেভাবে এটি করা পছন্দ করি:

 if (is_array(unserialize($serialized_string))):

সিরিয়ালযুক্ত ভেরিয়েবলটি একটি অ্যারে হওয়া উচিত কেন? এটি সত্যই যে কোনও ধরণের হতে পারে।
ভ্যালারিও বোজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.