Created
May 26, 2016 20:14
-
-
Save ohader/72f437972eed4d69280693b82ed1b82c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Utility | |
{ | |
/** | |
* @param string $data | |
* @param array $allowedClasses | |
* @param bool $extend | |
* @return mixed | |
*/ | |
static public function deserialize(string $data, array $allowedClasses, $extend = false) | |
{ | |
$additionalClasses = []; | |
$result = unserialize($data, ['allowed_classes' => $allowedClasses]); | |
if (!$extend) { | |
return $result; | |
} | |
$json = json_encode($result); | |
if ( | |
strpos($json, '__PHP_Incomplete_Class_Name') !== false | |
&& preg_match_all('#"__PHP_Incomplete_Class_Name":"([^\\"]+)"#', $json, $matches) | |
) { | |
foreach ($matches[1] as $index => $checkClass) { | |
if (static::extensible($allowedClasses, $checkClass)) { | |
$additionalClasses[] = $checkClass; | |
} | |
} | |
} | |
if (!empty($additionalClasses)) { | |
$allowedClasses = array_merge($allowedClasses, $additionalClasses); | |
$result = unserialize($data, ['allowed_classes' => $allowedClasses]); | |
} | |
return $result; | |
} | |
/** | |
* @param array $classes | |
* @param $checkClass | |
* @return bool | |
*/ | |
static protected function extensible(array $classes, string $checkClass): bool | |
{ | |
foreach ($classes as $class) { | |
if (is_a($checkClass, $class, true)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
} | |
interface InterfaceClass | |
{ | |
} | |
abstract class AbstractClass | |
{ | |
protected $value = ''; | |
public function show() { var_dump($this->value); } | |
} | |
class AA extends AbstractClass | |
{ | |
} | |
class BB extends AA implements InterfaceClass | |
{ | |
} | |
class CC extends BB | |
{ | |
protected $value = 'cc'; | |
} | |
$array = [ | |
'cc' => new CC() | |
]; | |
$s = serialize($array); | |
# $u = Utility::deserialize($s, [InterfaceClass::class], false); | |
$u = Utility::deserialize($s, [InterfaceClass::class], true); | |
# $u = unserialize($s, ['allowed_classes' => [InterfaceClass::class]]); | |
var_dump($u); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Instead of is_a one could also use is_subclass_of here as we only check for subclasses.
However, that is only relevant regarding which method is faster.
However, there is the possibility of a different approach to get the PHP incomplete classname:
Not sure which approach is faster.
However, this approach would only work for one array level.
Whereas the other should work for multiple levels.