Skip to content

Instantly share code, notes, and snippets.

@ajacques-quatral
Last active January 1, 2016 05:28
Show Gist options
  • Save ajacques-quatral/8098361 to your computer and use it in GitHub Desktop.
Save ajacques-quatral/8098361 to your computer and use it in GitHub Desktop.
First attempt to manage Attributes like C# property in PHP
<?php
/**
*
* This should be the base class for any other class in a project.
*
* @author ajacques
*
*/
class Object {
/**
*
* All the properties except those from Object class
*
* @var array
*/
private $properties = [];
/**
* Constructor - Load the properties into the $properties
*/
public function Object() {
$ref = new ReflectionClass($this);
$this->loadProperties($ref);
}
/**
*
* This function loads all the properties from the ReflectionClass received in parameter
*
* @param ReflectionClass $_ref
*/
private function loadProperties(ReflectionClass $_ref) {
$properties = $_ref->getProperties();
foreach ($properties as $property) {
if ($property->getDeclaringClass()->getName() !== 'Object') {
$this->properties[] = $property->getName();
}
}
}
/**
*
* This method is called when any type of reading is done into the code. It will check the syntax and if the
* property exists. If so, it return the value of this property. Otherwise, error will be thrown. Must be mapped
* to a get[Name] method.
*
* echo $Object->Value;
* Will call __get with $_name = 'Value'. Then if all validation is ok, it will call the function getValue(),
* where Value is $_name.
*
* @param string $_name
* @throws Exception - Invalid property name
* @throws Exception - Property [name] doesn't exists
* @return mixed
*/
public function __get($_name) {
if ($_name === ucfirst($_name)) {
if (in_array(lcfirst($_name), $this->properties)) {
return $this->{'get' . $_name}();
} else {
throw new Exception('Object - Property ' . $_name . ' doesn\'t exists');
}
} else {
throw new Exception('Object - Invalid property name');
}
}
/**
*
* This method is called when any type of affectation is done into the code. It will check the syntax and if the
* property exists. If so, it change the value of this property. Otherwise, error will be thrown. Must be mapped
* to a set[Name] method.
*
* Example
*
* $object->Value = 3;
* Will call __set with $_name = 'Value' and $_value = 3. Then if all validation is ok, it will call the
* function setValue(3) where Value is the $_name and 3 the $_value.
*
* @param unknown_type $_name
* @param unknown_type $_value
* @throws Exception
*/
public function __set($_name, $_value) {
if ($_name === ucfirst($_name)) {
if (in_array(lcfirst($_name), $this->properties)) {
return $this->{'set' . $_name}($_value);
} else {
throw new Exception('Object - Property ' . $_name . ' doesn\'t exists');
}
} else {
throw new Exception('Object - Invalid property name');
}
}
/**
*
* Will throw an error if no method has been declared.
*
* That way, you can define read-only attribute by not defining the set[Name] and it will trigger and exception.
*
* @param string $_name
* @param array $_arguments
* @throws Exception Method [name] doesn't exists
*/
public function __call($_name, $_arguments) {
throw new Exception('Object - Method ' . $_name . ' doesn\'t exists');
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment