property-accessor.php

Simple property accessor library
git clone git://git.finwo.net/lib/property-accessor.php
Log | Files | Refs

commit a92b6441a6f0fe290c41feaaa8615430285ee26a
parent f3f7f09c5794e8e10c889838ea3e420fb113ceec
Author: finwo <finwo@pm.me>
Date:   Wed, 13 Apr 2016 01:37:25 +0200

Added get methods for objects

Diffstat:
Aexample.php | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/PropertyAccessor.php | 87++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 153 insertions(+), 12 deletions(-)

diff --git a/example.php b/example.php @@ -0,0 +1,78 @@ +<?php + +//include composer's autoloader in this example +include __DIR__ . '/vendor/autoload.php'; + +use Finwo\PropertyAccessor\PropertyAccessor; + +class testObject +{ + public $pubVar = 'pubValue'; + + protected $proVar = 'proValue'; + protected $proAccessibleVar = 'proAccessibleValue'; + + private $priVar = 'priValue'; + private $priAccessibleVar = ''; + + /** + * @return mixed + */ + public function getProAccessibleVar() + { + return $this->proAccessibleVar; + } + + /** + * @param $proAccessibleVar + * @return $this + */ + public function setProAccessibleVar($proAccessibleVar) + { + $this->proAccessibleVar = $proAccessibleVar; + return $this; + } + + /** + * @return mixed + */ + public function getPriAccessibleVar() + { + return $this->priAccessibleVar; + } + + /** + * @param $priAccessibleVar + * @return $this + */ + public function setPriAccessibleVar($priAccessibleVar) + { + $this->priAccessibleVar = $priAccessibleVar; + return $this; + } + +} + +$obj = new testObject(); +$arr = array( + 'type' => 'person', + 'person' => array( + 'name' => 'John Doe', + 'age' => '40' + ) +); + +//accessor in debug mode +$acc = new PropertyAccessor(true); + +printf("\$obj->pubvar : %s\n", $acc->get($obj, 'pubVar')); +printf("\$obj->proVar : %s\n", $acc->get($obj, 'proVar')); +printf("\$obj->proAccessibleVar : %s\n", $acc->get($obj, 'proAccessibleVar')); +printf("\$obj->priVar : %s\n", $acc->get($obj, 'priVar')); +printf("\$obj->priAccessibleVar : %s\n", $acc->get($obj, 'priAccessibleVar')); + +print("\n"); + +printf("\$arr|type : %s\n", $acc->get($arr, 'type')); +printf("\$arr|person|name : %s\n", $acc->get($arr, 'person|name')); +printf("\$arr|person|age : %s\n", $acc->get($arr, 'person|age')); diff --git a/src/PropertyAccessor.php b/src/PropertyAccessor.php @@ -4,6 +4,13 @@ namespace Finwo\PropertyAccessor; class PropertyAccessor { + protected $debug = false; + + public function __construct($debug = false) + { + $this->debug = $debug; + } + /** * @param $subject * @param string $path @@ -14,15 +21,13 @@ class PropertyAccessor */ public function get($subject, $path = '', $pathSplit = '|') { - //split the path - $path = explode($pathSplit, $path); - - //try array + // try array for legacy mapper if (is_array($subject)) { + $path = explode($pathSplit, $path); return $this->getArrayProperty($subject, $path); } - //throw error if needed + // throw error if needed if (!is_object($subject)) { throw new \Exception(sprintf( 'Subject must be an array or object, %s given', @@ -30,7 +35,46 @@ class PropertyAccessor )); } - //all methods failed, throw exception + $camelized = $this->camelize($path); + + // try the default getter + if (method_exists($subject, $method = sprintf("get%s", $camelized))) { + return call_user_func(array( + $subject, + $method + )); + } + + // try less-common getter + if (method_exists($subject, $method = lcfirst($camelized))) { + return call_user_func(array( + $subject, + $method + )); + } + + // try generic getter + if (method_exists($subject, 'get')) { + return $subject->get($path); + } + + // try generic hidden getter + if (method_exists($subject, '__get')) { + return $subject->__get($path); + } + + // try fetching directly + $rc = new \ReflectionObject($subject); + foreach ($rc->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { + if ($property->getName() == $path) { + return $subject->{$path}; + } + } + + // all methods failed, throw exception + if ($this->getDebug()) { + return '#ERROR'; + } throw new \Exception(sprintf( 'Required property "%s" of class %s is missing in data', '', @@ -49,15 +93,13 @@ class PropertyAccessor */ public function set(&$subject, $path = '', $value, $pathSplit = '|') { - //split the path - $path = explode($pathSplit, $path); - - //try array + // try array for legacy mapper if (is_array($subject)) { + $path = explode($pathSplit, $path); return $this->setArrayProperty($subject, $path, $value); } - //throw error if needed + // throw error if needed if (!is_object($subject)) { throw new \Exception(sprintf( 'Subject must be an array or object, %s given', @@ -65,7 +107,11 @@ class PropertyAccessor )); } - //all methods failed, throw exception + // all methods failed, throw exception + if ($this->getDebug()) { + return '#ERROR'; + } + throw new \Exception(sprintf( 'Required property "%s" of class %s is missing in data', '', @@ -94,6 +140,23 @@ class PropertyAccessor $target = &$target[$key]; } $target = $value; + return $this; } + + /** + * Simple camelize function + * + * @param string $scored + * @return mixed + */ + protected function camelize( $scored = '' ) { + $output = str_replace(array('-', '_'), " ", $scored ); + return str_replace(' ','',ucwords($output)); + } + + protected function getDebug() + { + return $this->debug; + } } \ No newline at end of file