1
0
mirror of https://github.com/dg/dibi.git synced 2025-08-05 05:37:39 +02:00

* added NObject

This commit is contained in:
David Grudl
2007-11-08 21:35:30 +00:00
parent 8b99c00f91
commit 6492fe10b6
6 changed files with 234 additions and 46 deletions

View File

@@ -32,6 +32,7 @@ if (version_compare(PHP_VERSION , '5.1.0', '<')) {
// libraries // libraries
require_once __FILE__ . '/../libs/NObject.php';
require_once __FILE__ . '/../libs/driver.php'; require_once __FILE__ . '/../libs/driver.php';
require_once __FILE__ . '/../libs/resultset.php'; require_once __FILE__ . '/../libs/resultset.php';
require_once __FILE__ . '/../libs/translator.php'; require_once __FILE__ . '/../libs/translator.php';

229
dibi/libs/NObject.php Normal file
View File

@@ -0,0 +1,229 @@
<?php
/**
* Nette Framework
*
* Copyright (c) 2004, 2007 David Grudl aka -dgx- (http://www.dgx.cz)
*
* This source file is subject to the "Nette license" that is bundled
* with this package in the file license.txt.
*
* For more information please see http://php7.org/nette/
*
* @author David Grudl
* @copyright Copyright (c) 2004, 2007 David Grudl
* @license http://php7.org/nette/license (Nette license)
* @link http://php7.org/nette/
* @version $Revision$ $Date$
* @category Nette
* @package Nette-Core
*/
/**
* NObject is the ultimate ancestor of all instantiable classes.
*
* It defines some handful methods and enhances object core of PHP:
* - access to undeclared members throws exceptions
* - ability to add new methods to class (extension methods)
* - support for conventional properties with getters and setters
*
* Properties is a syntactic sugar which allows access public getter and setter
* methods as normal object variables. A property is defined by a getter method
* and optional setter method (no setter method means read-only property).
* <code>
* $val = $obj->Label; // equivalent to $val = $obj->getLabel();
* $obj->Label = 'Nette'; // equivalent to $obj->setLabel('Nette');
* </code>
* Property names are case-sensitive, and they are written in the PascalCaps,
* in contrast to camelCaps used by normal members.
*
* Adding method to class (i.e. to all instances) works similar to JavaScript
* prototype property. The syntax for adding a new method is:
* <code>
* function MyClass_prototype_newMethod(MyClass $obj, $arg, ...) { ... }
* $obj = new MyClass;
* $obj->newMethod($x); // equivalent to MyClass_prototype_newMethod($obj, $x);
* </code>
*/
abstract class NObject
{
/**
* Returns the name of the class of this object
*
* @return string
*/
final public function getClass()
{
return get_class($this);
}
/**
* Access to reflection
*
* @return ReflectionClass
*/
final public function getReflection()
{
return new ReflectionClass(get_class($this));
}
/**
* Return hash id for given object
*
* @return string 32 hexa chars
*/
final public function getHashId()
{
return spl_object_hash($this);
}
/**
* Call to undefined method
*
* @param string method name
* @param array arguments
* @return mixed
* @throws BadMethodCallException
*/
protected function __call($name, $args)
{
// object prototypes support Class__method()
// (or use class Class__method { static function ... } with autoloading?)
$cl = $class = get_class($this);
do {
if (function_exists($nm = $cl . '_prototype_' . $name)) {
array_unshift($args, $this);
return call_user_func_array($nm, $args);
}
} while ($cl = get_parent_class($cl));
throw new BadMethodCallException("Call to undefined method $class::$name()");
}
/**
* Returns property value. Do not call directly.
*
* @param string property name
* @return mixed property value or the event handler list
* @throws NPropertyException if the property is not defined.
*/
protected function &__get($name)
{
if ($name === '') {
throw new NPropertyException('Property name must be a non-empty string');
}
// property getter support
$class = get_class($this);
$m = 'get' . $name;
if (self::isCallable($class, $m)) {
// ampersands:
// - using &__get() because declaration should be forward compatible (e.g. with NHtml)
// - not using &$this->$m because user could bypass property setter by: $x = & $obj->property; $x = 'new value';
$val = $this->$m();
return $val;
} else {
throw new NPropertyException("Cannot read an undeclared property $class::\$$name");
}
}
/**
* Sets value of a property. Do not call directly.
*
* @param string property name
* @param mixed property value
* @return void
* @throws NPropertyException if the property is not defined or is read-only
*/
protected function __set($name, $value)
{
if ($name === '') {
throw new NPropertyException('Property name must be a non-empty string');
}
// property setter support
$class = get_class($this);
if (self::isCallable($class, 'get' . $name)) {
$m = 'set' . $name;
if (self::isCallable($class, $m)) {
$this->$m($value);
} else {
throw new NPropertyException("Cannot assign to a read-only property $class::\$$name");
}
} else {
throw new NPropertyException("Cannot assign to an undeclared property $class::\$$name");
}
}
/**
* Is property defined?
*
* @param string property name
* @return bool
*/
protected function __isset($name)
{
return $name !== '' && self::isCallable(get_class($this), 'get' . $name);
}
/**
* Access to undeclared property
*
* @param string property name
* @return void
* @throws NPropertyException
*/
protected function __unset($name)
{
$class = get_class($this);
throw new NPropertyException("Cannot unset an declared or undeclared property $class::\$$name");
}
/**
* Is method defined? Case sensitive, filters protected & private, doesn't recognize static methods (works good since 5.0.4)
*
* @param string class name
* @param string method name
* @return bool
*/
private static function isCallable($c, $m)
{
static $cache;
if (!isset($cache[$c])) {
$cache[$c] = array_flip(get_class_methods($c));
}
return isset($cache[$c][$m]);
}
}
/**
* Occurs on unsuccessful attempts to get or set the value of a property
*/
class NPropertyException extends Exception
{
}

View File

@@ -26,7 +26,7 @@
* *
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
abstract class DibiDriver abstract class DibiDriver extends NObject
{ {
/** /**
* Current connection configuration * Current connection configuration
@@ -300,15 +300,4 @@ abstract class DibiDriver
abstract public function applyLimit(&$sql, $limit, $offset = 0); abstract public function applyLimit(&$sql, $limit, $offset = 0);
/**#@+
* Access to undeclared property
* @throws Exception
*/
private function &__get($name) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
private function __set($name, $value) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
private function __unset($name) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
/**#@-*/
} // class DibiDriver } // class DibiDriver

View File

@@ -26,7 +26,7 @@
* *
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
final class DibiLogger final class DibiLogger extends NObject
{ {
/** @var string Name of the file where SQL errors should be logged */ /** @var string Name of the file where SQL errors should be logged */
private $file; private $file;
@@ -102,15 +102,4 @@ final class DibiLogger
fclose($handle); fclose($handle);
} }
/**#@+
* Access to undeclared property
* @throws Exception
*/
private function &__get($name) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
private function __set($name, $value) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
private function __unset($name) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
/**#@-*/
} }

View File

@@ -35,7 +35,7 @@
* *
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
abstract class DibiResult implements IteratorAggregate, Countable abstract class DibiResult extends NObject implements IteratorAggregate, Countable
{ {
/** /**
* Describes columns types * Describes columns types
@@ -492,16 +492,6 @@ abstract class DibiResult implements IteratorAggregate, Countable
/** end required Countable functions */ /** end required Countable functions */
/**#@+
* Access to undeclared property
* @throws Exception
*/
private function &__get($name) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
private function __set($name, $value) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
private function __unset($name) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
/**#@-*/
} // class DibiResult } // class DibiResult

View File

@@ -26,7 +26,7 @@
* *
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
final class DibiTranslator final class DibiTranslator extends NObject
{ {
/** @var string */ /** @var string */
public $sql; public $sql;
@@ -412,14 +412,4 @@ final class DibiTranslator
} }
/**#@+
* Access to undeclared property
* @throws Exception
*/
private function &__get($name) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
private function __set($name, $value) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
private function __unset($name) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
/**#@-*/
} // class DibiParser } // class DibiParser