Roman Neuhauser wrote:
> # [EMAIL PROTECTED] / 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

Reply via email to