Skip to content

Instantly share code, notes, and snippets.

@lisachenko
Created August 1, 2018 08:11
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lisachenko/b10c1b9ac7bfab7adbe37e6878544f40 to your computer and use it in GitHub Desktop.
Save lisachenko/b10c1b9ac7bfab7adbe37e6878544f40 to your computer and use it in GitHub Desktop.
Private class instantinators
<?php
/**
* Sealed class can not be created directly
*/
class Seal
{
private function __construct()
{
// private ctor prevents from direct creation of instance
}
}
#1 Via traditional reflection without constructor
$refClass = new ReflectionClass(Seal::class);
$instance = $refClass->newInstanceWithoutConstructor();
var_dump($instance);
#2 Via closure binding to the sealed class
$instantinator = function () {
return new static;
};
$instantinator = $instantinator->bindTo(null, Seal::class);
$instance = $instantinator();
var_dump($instance);
#3 Via unserialize hack
$instance = unserialize(sprintf('O:%d:"%s":0:{}', strlen(Seal::class), Seal::class));
var_dump($instance);
#4 Via PDO, requires pdo_sqlite which is typically available, can be pdo_mysql, then change: SELECT "test" FROM DUAL
if (phpversion('pdo_sqlite')) {
$database = new PDO('sqlite::memory:');
$result = $database->query('SELECT "test" as field1'); // We can even initialize properties in the object
$instance = $result->fetchObject(Seal::class);
var_dump($instance);
}
#5 Via STOMP, requires php_stomp to be loaded
if (phpversion('stomp')) {
$connection = new Stomp(/* connection args */);
$connection->subscribe('Test');
$connection->readFrame(Seal::class);
}
@lisachenko
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment