Skip to content

Instantly share code, notes, and snippets.

@lynsei
Last active February 3, 2022 23:21
Show Gist options
  • Save lynsei/acdd0ae28ff824817106 to your computer and use it in GitHub Desktop.
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
<?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