首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP :不允许序列化闭包

PHP :不允许序列化闭包
EN

Stack Overflow用户
提问于 2016-10-05 23:45:42
回答 1查看 8.6K关注 0票数 3

整个场景是,我在我的opencart商店中添加了facebook登录扩展,当新用户单击登录时,使用facebook添加电子邮件和密码,然后单击登录,就会出现一个确认登录对话框,其中有两个按钮“取消”和“登录”,如果用户单击登录,它会将用户带到我的存储区,但是当用户单击“取消”时,它应该会将用户带回到我的商店的登录页面,但是它反而会给出错误的"Fatal error : uncaught exception with a message serialization of closure is not allowed

对于这一行"$_SESSION["HA::STORE"][$key] = serialize($value);,我使用了以下函数,其中包含这一行:

代码语言:javascript
复制
public function set( $key, $value)
    {
        $key = strtolower( $key );

        $_SESSION["HA::STORE"][$key] = serialize($value);
    }

我已经尝试过这个var_dump(序列化($value));它返回一个字符串--如何序列化这个字符串?我已经找过了,但没有找到任何有用的解决办法。

最新情况:

代码语言:javascript
复制
function login()
    {
        Hybrid_Logger::info( "Enter Hybrid_Provider_Adapter::login( {$this->id} ) " );

        if( ! $this->adapter ){
            throw new Exception( "Hybrid_Provider_Adapter::login() should not directly used." );
        }

        // clear all unneeded params
        foreach( Hybrid_Auth::$config["providers"] as $idpid => $params ){
            Hybrid_Auth::storage()->delete( "hauth_session.{$idpid}.hauth_return_to"    );
            Hybrid_Auth::storage()->delete( "hauth_session.{$idpid}.hauth_endpoint"     );
            Hybrid_Auth::storage()->delete( "hauth_session.{$idpid}.id_provider_params" );
        }

        // make a fresh start
        $this->logout();

        # get hybridauth base url
        $HYBRID_AUTH_URL_BASE = Hybrid_Auth::$config["base_url"];

        # we make use of session_id() as storage hash to identify the current user
        # using session_regenerate_id() will be a problem, but ..
        $this->params["hauth_token"] = session_id();

        # set request timestamp
        $this->params["hauth_time"]  = time();

        # for default HybridAuth endpoint url hauth_login_start_url
        #   auth.start  required  the IDp ID
        #   auth.time   optional  login request timestamp
        $this->params["login_start"] = $HYBRID_AUTH_URL_BASE . ( strpos( $HYBRID_AUTH_URL_BASE, '?' ) ? '&' : '?' ) . "hauth.start={$this->id}&hauth.time={$this->params["hauth_time"]}";

        # for default HybridAuth endpoint url hauth_login_done_url
        #   auth.done   required  the IDp ID
        $this->params["login_done"]  = $HYBRID_AUTH_URL_BASE . ( strpos( $HYBRID_AUTH_URL_BASE, '?' ) ? '&' : '?' ) . "hauth.done={$this->id}";

        Hybrid_Auth::storage()->set( "hauth_session.{$this->id}.hauth_return_to"    , $this->params["hauth_return_to"] );
        Hybrid_Auth::storage()->set( "hauth_session.{$this->id}.hauth_endpoint"     , $this->params["login_done"] ); 
        Hybrid_Auth::storage()->set( "hauth_session.{$this->id}.id_provider_params" , $this->params );

        // store config to be used by the end point 
        Hybrid_Auth::storage()->config( "CONFIG", Hybrid_Auth::$config );

        // move on
        Hybrid_Logger::debug( "Hybrid_Provider_Adapter::login( {$this->id} ), redirect the user to login_start URL." );

        Hybrid_Auth::redirect( $this->params["login_start"] );
    }

在function_login中,set()由以下代码调用:

代码语言:javascript
复制
Hybrid_Auth::storage()->set( "hauth_session.{$this->id}.hauth_return_to"    , $this->params["hauth_return_to"] );
        Hybrid_Auth::storage()->set( "hauth_session.{$this->id}.hauth_endpoint"     , $this->params["login_done"] ); 
        Hybrid_Auth::storage()->set( "hauth_session.{$this->id}.id_provider_params" , $this->params );
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-05 23:56:50

我猜您正在传递或被传递一个闭锁作为set()$value参数。

您需要使用反射检查和忽略闭包。

代码语言:javascript
复制
public function set( $key, $value)
{
    if (is_object($value)) {
        try {
            $reflection = new ReflectionFunction($value);
            if ($reflection->isClosure()) {
                //Trigger a E_USER_NOTICE if you want to avoid silently failing
                trigger_error("You cannot pass a closure as the second parameter of set()");
                return; // Do nothing else
            }
        } catch (\ReflectionException $e) {
            // Catch the exception thrown if $value is not a closure
        }
    }
    $key = strtolower( $key );

    $_SESSION["HA::STORE"][$key] = serialize($value);
}

或者您可以捕获并忽略异常:

代码语言:javascript
复制
function set( $key, $value)
{
    $key = strtolower( $key );
    try{
        $_SESSION["HA::STORE"][$key] = serialize($value);
    } catch (\Exception $e) {
        // Catch the exception thrown and handle it however you want
    }
}

或者看看这个用于序列化闭包的github项目

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39885355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档