I'm new to PHP but have worked with JavaScript quite a bit. I was trying to do the following:
class MyClass {
private $someAnonymousFunction = function($any){
return $any;
};
$data = [
['some String', $someAnonymousFunction]
];
}
But it comes up with an error when I create someAnonymousFunction saying it doesn't like that I put function (unexpected 'function' (T_FUNCTION)) in there like that. I've tried different scenarios beyond the above example but it seems the same errors happen.
Update Why I want to do this. I want to do this because I want to abstract away much of the boiler plate in creating classes. If I'm going to be writing code over and over, I would like to make it at easy and straight forward as possible. Below is my code in full (note that this was just for class and I'm taking it far beyond what it needs to be):
abstract class Protection {
const Guard = 0;
const Open = 1;
}
abstract class __ {
public function identity($any) {
return $any;
}
}
// This is the core logic behind the class
trait Property {
public function get($name) {
if ($this->data[$name][1] == Protection::Open) {
return $this->data[$name][0];
}
else {
//throw error
}
}
public function set($name, $set) {
if ($this->data[$name][1] == Protection::Open) {
//Guard function can throw error or filter input
$func = $this->data[$name][2];
$this->data[$name][0] = $func($set);
return $this;
}
else {
// throw error
}
}
}
class Monster {
use Property;
//Just trying to get this to work. Throws error.
private $identity = function($any) {
return $any;
};
private $data = [
'hairColor' => [
'brown',
Protection::Open,
ucwords
],
'killType' => [
'sword',
Protection::Open,
__::identity //Doesn't work either thinks it's a constant.
]
];
}
$generic = new Monster();
echo '<br> Hair color: ' . $generic->get('hairColor') . ', Kill type: '
. $generic->get('killType') . '<br>';
$generic->set('hairColor', 'blue')->set('killType', 'silver bullet');
Update 2: Here's the "final" code:
<?php
class Utils {
static function identity($any) {
return $any;
}
}
// Property abstracts much of the boiler plate away
// from making classes with getters and setters.
// It is chainable by default.
// It takes a variable named `data` which holds an
// associative array, with the keys being the names
// of the properties/methods. The key holds a value
// which is an indexed array where:
// Index 0 == Value of property.
// [Index 1] == Optional string name of guard function.
// [Index 2] == Optional string name of method called
// with `get` method.
// It has two public methods:
// `get` returns value of property or calls a method.
// `set` gives a new value to a property.
trait Property {
// Create a new property with attributes in an array.
private function createNewProperty($name, $set) {
$this->data[$name] = (is_array($set)) ? $set : [$set];
}
// Return property value
public function get($name) {
// If the property doesn't exist throw an error.
if (!isset($this->data[$name])) {
throw new Exception('No such property or method '.$name);
}
// copy by reference value into differently
// named variable to make code more concise.
$prop =& $this->data[$name];
// determine if property is a method.
if (isset($prop[2]) && $prop[2]) {
// call method with property value
return call_user_func($prop[2], $prop[0]);
}
else {
//return plain property value
return $prop[0];
}
}
// Set property value
public function set($name, $set) {
// If property isn't set then create one
if (!isset($this->data[$name])) {
createNewProperty($name, $set);
}
// copy by reference value into differently
// named variable to make code more concise.
$prop =& $this->data[$name];
// determine if guards exist when setting property
if (isset($prop[1]) && $prop[1]) {
$prop[0] = call_user_func($prop[1], $set);
return $this; // make chainable
}
else {
// set plain property
$prop[0] = $set;
return $this; // make chainable
}
}
}
class Monster {
use Property;
private $data = [
'hairColor' => ['brown', ['Utils', 'identity']],
'killType' => ['sword', 'ucwords'],
'simple' => ['simple value', null, 'ucwords'],
];
}
$generic = new Monster();
echo '<br> Hair color: ' . $generic->get('hairColor') . ', Kill type: '
. $generic->get('killType') . '<br>';
$generic->set('hairColor', 'blue')->set('killType', 'silver bullet');
echo '<br> Hair color: ' . $generic->get('hairColor') . ', Kill type: '
. $generic->get('killType') . '<br>';
echo '<br>Simple: '.$generic->get('simple');
$generic->set('simple', 'simple value changed!');
echo '<br>Simple: '.$generic->get('simple');
?>
__callmagic method`__callbut it doesn't look like it would fit my situation. I updated the question to let you know more fully what I am looking for.__::identityas a callback; the correct formats are described here: php.net/manual/en/language.types.callable.php In this case, either'__::identity'as a string, or more commonly['__', 'identity']as a 2 element array listing scope and method.