PHP : 不允许序列化闭包
PHP : Serialization of a closure is not allowed
整个场景是我在我的 opencart 商店中添加了 facebook 登录扩展,当新用户单击使用 facebook 登录添加电子邮件和密码并单击登录然后出现一个确认登录对话框时一切正常,它有两个按钮 "cancel" 和 "login" 如果用户单击登录,它会将用户带到我的商店,但是当用户单击 "cancel" 时,它应该将用户带回我商店的登录页面,但它会给出错误 "Fatal error : uncaught exception with a message serialization of closure is not allowed
这是这条线
"$_SESSION["HA::STORE"][$key] = serialize($value);
我正在使用包含此行的以下函数:
public function set( $key, $value)
{
$key = strtolower( $key );
$_SESSION["HA::STORE"][$key] = serialize($value);
}
我试过了
var_dump(序列化($值));它 returns 一个字符串
我怎样才能序列化这个?我已经搜索过了,但没有找到任何有用的解决方案
更新:
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() 是这样调用的:
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 );
我猜你正在传递或被传递 closure 作为 set()
的 $value
参数。
您需要使用 reflection
检查和忽略闭包
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);
}
或者您可以捕获并忽略异常:
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
}
}
整个场景是我在我的 opencart 商店中添加了 facebook 登录扩展,当新用户单击使用 facebook 登录添加电子邮件和密码并单击登录然后出现一个确认登录对话框时一切正常,它有两个按钮 "cancel" 和 "login" 如果用户单击登录,它会将用户带到我的商店,但是当用户单击 "cancel" 时,它应该将用户带回我商店的登录页面,但它会给出错误 "Fatal error : uncaught exception with a message serialization of closure is not allowed
这是这条线
"$_SESSION["HA::STORE"][$key] = serialize($value);
我正在使用包含此行的以下函数:
public function set( $key, $value)
{
$key = strtolower( $key );
$_SESSION["HA::STORE"][$key] = serialize($value);
}
我试过了 var_dump(序列化($值));它 returns 一个字符串 我怎样才能序列化这个?我已经搜索过了,但没有找到任何有用的解决方案
更新:
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() 是这样调用的:
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 );
我猜你正在传递或被传递 closure 作为 set()
的 $value
参数。
您需要使用 reflection
检查和忽略闭包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);
}
或者您可以捕获并忽略异常:
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
}
}