Last active
February 3, 2022 23:21
-
-
Save lynsei/acdd0ae28ff824817106 to your computer and use it in GitHub Desktop.
[lambda php code] repurposing this older code for some crypto project I'm working on #crypto #php #lambda #closures
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 | |
/* | |
Creator: Lynsei | |
On: 11. December 2015 */ | |
/* | |
The following code is just a reminder of why I'm using Closures to develop the object model | |
These examples start with a SessionStorage overhead class that a User class is dependent upon | |
The next set of functions shows a better way to do it with closures. | |
I'm considering using closures for functons to manage user data key/value pair storage | |
that's why I'm auditing this functionality really quickly | |
*/ | |
echo "<pre>"; | |
/* | |
class SessionStorage | |
{ | |
function __construct($cookieName = 'PHP_SESS_ID') | |
{ | |
session_name($cookieName); | |
session_start(); | |
} | |
function set($key, $value) | |
{ | |
$_SESSION[$key] = $value; | |
} | |
function get($key) | |
{ | |
return $_SESSION[$key]; | |
} | |
} | |
*/ | |
/* users->class *``~x&*``^ | |
* | |
* A simple construct for a user class | |
* | |
* -CHO | |
** rexNote->end *``^~x&*``^ */ | |
/* | |
class User | |
{ | |
protected $storage; | |
function __construct() | |
{ | |
$this->storage = new SessionStorage(); | |
} | |
function setLanguage($language) | |
{ | |
$this->storage->set('language', $language); | |
} | |
function getLanguage() | |
{ | |
return $this->storage->get('language'); | |
} | |
} | |
*/ | |
/* example->usage | |
* | |
* So obviously the above example means the User object is creating a SessionStorage object within it, but this | |
* is not a great idea because there is no way to modify the properties of the SessionStorage object or the user | |
* object easily when you take this route. This is where closures and lambda functions come into play. | |
* | |
* | |
*/ | |
/* example->usage */ | |
/* | |
$user = new User(); | |
$user->setLanguage('fr'); | |
$user_language = $user->getLanguage(); | |
echo $user_language; | |
*/ | |
/* | |
* | |
* class Twittee is the "smallest, and still useful" Dependency Injection rex. | |
* | |
* | |
***/ | |
class Twittee { | |
protected $s=array(); | |
function __set($k, $c) { $this->s[$k]=$c; } | |
function __get($k) { return $this->s[$k]($this); } | |
} | |
/* | |
* | |
* class Rex is a bit more elaborate of a container, and supports shared instances | |
* | |
** */ | |
class Rex // container object | |
{ | |
protected $values = array(); | |
function __set($id, $value) | |
{ | |
$this->values[$id] = $value; | |
} | |
function __get($id) | |
{ | |
if (!isset($this->values[$id])) | |
{ | |
throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id)); | |
} | |
return is_callable($this->values[$id]) ? $this->values[$id]($this) : $this->values[$id]; | |
} | |
function asShared($callable) | |
{ | |
return function ($c) use ($callable) | |
{ | |
static $object; | |
if (is_null($object)) | |
{ | |
$object = $callable($c); | |
} | |
return $object; | |
}; | |
} | |
} | |
/* | |
* | |
* These are the class definitions I was toying with, so as you can see it would be quite easy to adapt these | |
* to the skel language and use them for data modeling. Matter of fact I think we could easily convert | |
* all the table data into a set of objects automatically, which would be highly useful if we were going to | |
* fully flesh out an event driven model. Because then all the data that is in both the JSON-API from WP, | |
* and the data that is stored in key/value pairs in dyanmodb, or as flat files such as JSON / CSV could all | |
* be manipulated and cached easily. Since all of the data uses the wordpress db it's master repository, | |
* I am envisioning a process by which the entire system caches a mysql snapshot once every 5-10 minutes using | |
* a JSON master file or key/value storage faculty. Then we we just query all the listings data from that cache | |
* to spare the hits on mysql. If a record is edited, of course it will be pulling from the mysql data set (not the cache). | |
* but having the entire data set as objects would make it really easy to both use it in the api, automate sencha | |
* object creation, and just generally would advance the interoperability of the system overall. | |
* | |
* -CHO | |
***/ | |
class RexSession | |
{ | |
public $cookie; | |
public $password; | |
public $username; | |
public $session_id; | |
public $rsa_key; | |
public $serialized = array(); | |
public $tokens = array(); | |
public $repeat_tokens; | |
} | |
class RexUser | |
{ | |
public $name; | |
public $role; | |
public $email; | |
public $phone; | |
public $wp_capabilities = array(); | |
public $repeat_storage; | |
} | |
class RexAmazonIAM | |
{ | |
public $aws_secret; | |
public $aws_keyid; | |
public $iam_group; | |
public $iam_permissons_serialized; | |
public $aws_commands; | |
} | |
/*^ | |
* | |
* Here I'm instantiating a container, and that container is employing | |
* the use of closures to distribute data objects. This way both the objects | |
* and their configuration can remain flexible and interdependent, yet there is lots | |
* of flexibility as to how to architect, and for how you can recycle the data. | |
* | |
***/ | |
$rex = new Rex(); | |
// define the objects | |
$rex->storage = $rex->asShared(function ($c) | |
{ | |
return new $c->storage_class($c->cookie); | |
}); | |
// repeating with a new property to see what happens | |
$rex->repeated_storage = $rex->asShared(function ($c) | |
{ | |
return new $c->storage_class($c->cookie); | |
}); | |
$rex->user = function ($c) | |
{ | |
static $object; | |
if (is_null($object)) | |
{ | |
$object = new User($c->storage, $c->repeat_storage); | |
} else { | |
throw new InvalidArgumentException(sprintf('Storage "%s" is not an object.', $object)); | |
} | |
return $object; | |
}; | |
/* | |
* | |
* This is how I've been playing with instantiating the data sets | |
* and it's shown me a lot. These really do provide and intriniscally flexible | |
* data set. I used to use functions that stored magic properties with this syntax: | |
* object()->blah. In the past I used Magic Methods and abstract class extensions to | |
* achieve a similar thing. It was mostly for when I was building frameworks that | |
* had really complex configurations. | |
* | |
* The code looked like this: | |
* | |
* abstract class PropertyObject | |
* { | |
* public function __get($name) | |
* { | |
* if (method_exists($this, ($method = 'get_'.$name))) | |
* { | |
* return $this->$method(); | |
* } | |
* else return; | |
* } | |
* | |
* public function __isset($name) | |
* { | |
* if (method_exists($this, ($method = 'isset_'.$name))) | |
* { | |
* return $this->$method(); | |
* } | |
* else return; | |
* } | |
* | |
* public function __set($name, $value) | |
* { | |
* if (method_exists($this, ($method = 'set_'.$name))) | |
* { | |
* $this->$method($value); | |
* } | |
* } | |
* | |
* public function __unset($name) | |
* { | |
* if (method_exists($this, ($method = 'unset_'.$name))) | |
* { | |
* $this->$method(); | |
* } | |
* } | |
* } | |
* | |
* So as you can see it was a similar concept, but I do like the closures a lot better | |
* and I'm pretty sure that the magic methods didn't handle objects being passed to them | |
* the same way, and it was less controllable of an outcome. So I think I'll definitely | |
* be using these in the future. | |
* | |
**/ | |
// define the parameters | |
$rex->cookie = 'SESSION_ID'; | |
$rex->storage_class = 'RexSession'; | |
$rex->user = new RexUser(); | |
$user = $rex->user; | |
$user->name= 'cho'; | |
$user->role= 'admin'; | |
// create a storage object | |
$storage['test2'] = $rex->storage; | |
$storage['test2']->cookie = 'omgcookiemonster'; | |
$storage['test2']->serialized = 'aoijasfjnsdfffs989a8f9as'; | |
$storage['test2']->username = 'chogan'; | |
$storage['test2']->password = '2Legit2Quit'; | |
$storage['test2']->role_reality = 'admin'; | |
// create a storage object #2 | |
$storage['test1'] = $rex->storage; | |
$storage['test1']->cookie = 'omgcookiemonster'; | |
$storage['test1']->serialized = 'aoijasfjnsdfffs989a8f9as'; | |
$storage['test1']->username = 'cho'; | |
$storage['test1']->password = '2Legit2Quit'; | |
$storage['test1']->role_reality = 'admin'; | |
// assign a storage object to the user object | |
$rex->user->storage = $storage; | |
print_r ($user); | |
echo "REX[user]\n"; | |
print_r ($rex->user); | |
echo "REX[repeated_storage]\n"; | |
print_r ($rex->repeated_storage); | |
echo "REX[cookie]\n"; | |
echo $rex->cookie; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment