Re: Json.php

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Roman Neuhauser wrote:
> # chris.boget@xxxxxxxx / 2007-04-18 04:59:48 -0400:
>>> So only one of these is "kosher"
>>> static:
>>> return Services_JSON::decode($data);
>>>
>>> class:
>>> $json = new Services_JSON;
>>> return $json->decode($data);
>>> but not both.
>> I'm not trying to start (or further add fuel to) any kind of war but 
>> instead an earnest question: why not both?
> 
> If you don't declare the method static, you might be using $this inside,
> possibly indirectly.
> 
> class c
> {
>     function f()
>     {
>         if (its_second_friday_this_year()) {
>             return get_class($this);
>         }
>         return 'mostly harmless';
>     }
>     function g()
>     {
>         return self::f();
>     }
> }
> 
> c::g();
> 
> That's an incident waiting to happen, and forbidding static calls of
> instance methods is an (intended) anti-footshooting measure.

nothing an isset($this) didn't/doesn't solve - they gave me the php gun, so
let me decide whether or not to and potential foot/head shots in my code ...
thats my opinion anyway .. not that it counts for much.

but a practical question for you Roman (seeing as your very much into OOP),
how would you write a single method that could be called statically or not so that
one can transparently use the same method to do stuff in different contexts?

maybe an example would help (severely cutdown code):

class DB {
	public function conn()
	{
        	$confClass = self::getConfClass();
        	return self::_conn($confClass);
	}

	private function _conn($confClass)
    	{
        	static $dbConn = array();

		if (isset($this) && isset($this->transid))
			return $this->transid;

        	if (!isset($dbConn[$confClass])) {
			// set up a new connection and
			// store id in $dbConn[$confClass]
		}

		return $dbConn[$confClass];
	}

	function query($sql) {
		// get ibase connection OR transaction id
		// depending on whether we are an object with a transid or not
		$connId = self::conn();

        	$args = func_get_args();
	        $args = self::resolveArgs($args);
        	array_unshift($args, $connId);

		// the return val from ibase_query is actually
		// wrapped in a ResultSet object in the real code
		return call_user_func_array('ibase_query', array_values($args));
	}
}

the above class can be used in 2 ways:

1. statically - allowing simple queries in the default implicit transaction of the
'current' connection:

DB::query("SELECT * FROM foo WHERE id=?", $id);

2. a method call of a DB object (which means one uses an automatically created
explicit transaction for all calls via that instance of DB, within the context
of the 'current' connection)

$db  = new DB(); // start an explicit transaction
try {
	$db->query("SELECT * FROM foo WHERE id=?", $id);
	$db->query("UPDATE foo SET bar=? WHERE id=?", 'cheese', $id);
	$db->commit();	
} catch (DBException $e) {
	$db->rollback();
}

now I understand that you might be inclined to say the design is bad - which
is fair enough - but please realise my question is not whether is should be done
but how. consider that this question arises because I have a DB class that works this
way and when it was written (in conjunction with a nice guy named Ard Biesheuvel,
a very clever chap, who has done some work on the actual php engine and the firebird extension)
the code was legal and works like a charm (and 10000's of lines of code are in use/production).



> 


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux