Suggestions for PHP 6

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Suggestions for PHP 6

Post by alex.barylski »

I had a situataion when I needed finally statement, but frankly I can't remember what was the case And I'm pretty sure it wasn't about anything the GC could do.
I hear you...how many times I have thought 'feature x' would be cool but couldn't remember why. :P
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Suggestions for PHP 6

Post by John Cartwright »

If I had to ask for 1 thing for Christmas, I think it would be multiple inheritance. I can always dream...
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Suggestions for PHP 6

Post by VladSun »

John Cartwright wrote:If I had to ask for 1 thing for Christmas, I think it would be multiple inheritance. I can always dream...
Interesting :) I would ask for prototype based OOP PHP, not class based :P
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Suggestions for PHP 6

Post by Christopher »

John Cartwright wrote:If I had to ask for 1 thing for Christmas, I think it would be multiple inheritance. I can always dream...
My guess is that what you really want is mixins, not multiple inheritance -- which quickly becomes an overriding nightmare because of the diamond problem.
(#10850)
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Suggestions for PHP 6

Post by John Cartwright »

arborint wrote:
John Cartwright wrote:If I had to ask for 1 thing for Christmas, I think it would be multiple inheritance. I can always dream...
My guess is that what you really want is mixins, not multiple inheritance -- which quickly becomes an overriding nightmare because of the diamond problem.
The concept of mixins is new to me, however after a quick wikipedia search it appears to be exactly wanted (but just didn't know it yet).

//edits his Christmas list :)
VladSun wrote:
John Cartwright wrote:If I had to ask for 1 thing for Christmas, I think it would be multiple inheritance. I can always dream...
Interesting :) I would ask for prototype based OOP PHP, not class based :P
Touche. (accent aigu).

I'm curious though, as others have pointed out, multiple inheritance doesn't seem to belong in "scripting" languages, why is this? I would assume from a technical standpoint PHP object model would need some serious upgrading, but that doesn't explain the generalization of why "scripting" languages should'nt support such.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Suggestions for PHP 6

Post by Weirdan »

PCSpectra wrote:What kind of resources would you need to release in a PHP application that the GC doesn't do you for intrinsically?
Any resources not managed by php, or these which are normally released only in RSHUTDOWN phase. Like mutexes stored in external memory (memcache), or database transactions which have to be rolled back if they are unable to complete (and before starting another transaction). For mutexes I have to rely on mutex object destructor being called (and it's called only when gc decides it needs to, which is not when I want it called) or explicitly release mutex and rethrow an exception:

Code: Select all

 
function getSomeData() {
    $data = Cache::get('data');
    if (!$data->expired()) {
         return $data;
    }
 
    $mutex = new Mutex('mutexName');
    if ($mutex->obtained()) {
        // I would like to be able to do the following:
        //   try {
        //         // do some heavy processing
        //         Cache::store('data', $data);
        //   } finally {
        //        $mutex->release();
        //   }
        try {
            // do some heavy processing that should not be run in parallel. Here an exception may occur
            // results in $data being populated
            Cache::store('data', $data)
        } catch (Exception $e) {
            $mutex->release();
            throw $e;
        }
        $mutex->release(); // code duplication, but unavoidable
    }
    
    return $data; // it's better to return expired data than make client wait 
                  // while fresher data is being prepared (by another process) at the moment  
                  // and will be available soon (likely on next client request)
}
 
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Suggestions for PHP 6

Post by josh »

Using MI is like admitting you want to save 2 seconds at the cost of making all your code statically coupled, I think the "difficulty" of following indirection of a composite based design pays off on multiple factors. I thought mixins were a form of MI you just have to statically call each method, the key word here is static though, either way you're up to your waist in static dependencies, a re factoring nightmare
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Suggestions for PHP 6

Post by alex.barylski »

I'm curious though, as others have pointed out, multiple inheritance doesn't seem to belong in "scripting" languages, why is this?
It's not just scripting languages. MI works fine if it's used sparingly as I mention previously.

Consider a MI like

Code: Select all

 
       /- Child1-\
Base               ChildChild
       \_ Child2_/
 
ChildChild now has a dual inheritence.

What happens if both Child1 and Child2 declare a common method and signature? When the object of ChildChild invokes that method, which ChildX method gets called?

Likewise, with MI you will experience more fragile hierarchies. A change in the interface for Base would possibly percolate into the Child1 and Child2 interfaces and thus into any of their children, etc. MI inheritence has the nasty effect of making already fragile single inheritence hierarchies arbitrarally more complex and thus fragile.

Consider what happens when you have a single inheritence family of classes like:

Code: Select all

Base
  Child
    GrandChild
Assume Base has a method whose signature changes and it's used by multiple objects of instance GrandChild. A change in the base class now requires you update multiple uses of any of it's child objetcs that rely on that inherited method.

It's a PITA to say the least...now take that search & replace excersize and multiple by however many of times that base class has been used in a MI scenario.
Like mutexes stored in external memory (memcache), or database transactions which have to be rolled back if they are unable to complete (and before starting another transaction). For mutexes I have to rely on mutex object destructor being called (and it's called only when gc decides it needs to, which is not when I want it called) or explicitly release mutex and rethrow an exception:
What are you doing in PHP that would require the use of Mutex's? :)

Cheers,
Alex
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Suggestions for PHP 6

Post by Weirdan »

PCSpectra wrote:What are you doing in PHP that would require the use of Mutex's? :)
Nothing special actually, just running a lot of web servers using single database and single cache server. Consider the following situation: a cache item has expired. As caching is usually employed on most expensive (or most common) operations, and webservers are still under usual load (say 100 requests per second), there is high possibility that a lot of client connections will need that item at the same moment. They will go to cache server, learn that item is no longer valid and all of them will attempt to recalculate it from database data. And now you have your database server executing hundreds of identical expensive queries, doing it slow, and more and more clients coming in asking for that same data, which only makes it even slower. Great chances it will bring it to its knees. When cache server goes down the situation is even worse (because all cached data is lost).

Mutex is a great (and simple to implement) way to prevent this situation.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Suggestions for PHP 6

Post by josh »

weirdDan thats interesting I thought it was just for structuring code based on MI. Looks like that only applies to threads though. Could the same effect achieved ( albeit not as cleanly ) by having a database table in charge of locks for accessing this cache, and require exclusive write locks to attain a lock key, after a thread got the lock it would re-read to check for inconsistent reads, build the cache and then release the lock? Sounds like threads are a better way to handle it though obviously
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Suggestions for PHP 6

Post by Weirdan »

josh wrote:Could the same effect achieved ( albeit not as cleanly ) by having a database table in charge of locks for accessing this cache,
Any storage that provides atomic saving and accessible to all webservers could be used to implement such mutually exclusive execution. And for mutexes inconsistent read is not a problem, as you are never really reading lock status, only writing it:

Code: Select all

 
/*
  `locks` table have the following structure:
  create table locks (
       name char(32) unique -- unique key on name column is important
  ) engine=HEAP;
*/
class Mutex_Db implements Mutex_Interface {
      protected $_obtained = false;
      protected $_name = '';
      protected $_db = null;
 
      public function __construct($name) {
           $this->_name = $name;
           $this->_db = Registry::getDb(); // obtain reference to connection object so it won't be destroyed
                                                          // earlier than this mutex (we need db access in destructor).
           $this->obtain();
      }
 
      public function obtain() {
           if ($this->obtained()) return true;
           // query() returns false if such lock is already set
           $this->_obtained = (bool) $this->_db->query('insert into locks set name=?', $this->_name);
           return $this->obtained();
      }
 
      public function obtained() {
           return (bool) $this->_obtained;
      }
 
      public function release() {
           $this->_db->query('delete from locks where name=?', $this->_name);
           $this->_obtained = false;
      }
 
      public function __destruct() {
           $this->release();
      }
}
 
 
There are no problems with this approach, but memcache implementation is faster and have some added benefits like storing locks alongside with data they protect access to (so when cache server goes down all locks disappear). Also it allows to set timeouts on keys, so if process holding the lock hangs, the lock would be automatically released after a period of time. And it scales better than databases (I haven't tried mysql sharding support yet, though).
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Suggestions for PHP 6

Post by Eran »

- Normalize isset(), empty(), is_null() behavior
- Bytecode caching as a language feature (integrate and improve one of the existing projects)
- first-order and real anonymous functions (a-la Javascript)
- __toArray() magical method for classes
- Improve error messages
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Suggestions for PHP 6

Post by Weirdan »

pytrin wrote:- Normalize isset(), empty(), is_null() behavior
hmm... in what regards they are not normal now?
pytrin wrote: - Bytecode caching as a language feature (integrate and improve one of the existing projects)
PHP is gonna be shipped with APC built-in.
pytrin wrote: - first-order and real anonymous functions (a-la Javascript)
This is gonna happen: http://wiki.php.net/rfc/closures
pytrin wrote: - __toArray() magical method for classes
Isn't implementing ArrayAccess enough? Why would you need real arrays?
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Suggestions for PHP 6

Post by Eran »

hmm... in what regards they are not normal now?
The main problem is with null values - it's hard to tell apart not existing variables from variables set to null. This is most commonly used in testing array keys (for example, a database row set which can include null values).

Code: Select all

$test = array(0 => 'test',1 => null);
var_dump(isset($test[1])); //returns false
var_dump(is_null($test[1])); //returns true
 
var_dump(isset($test[2])); //returns false
var_dump(is_null($test[2])); //returns true
empty() also has somewhat unexpected behavior with different types of variables.
PHP is gonna be shipped with APC built-in.
That's great! APC is my favorite bytecode cache.
Isn't implementing ArrayAccess enough? Why would you need real arrays?
Not really, I don't want to implement the entire ArrayAccess interface. I just want an object to have a defined toArray() behavior when acted upon with array functions / accessors (similar to __toString() ). This magical method should return an array - which PHP can easily handle.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Suggestions for PHP 6

Post by Weirdan »

pytrin wrote: The main problem is with null values - it's hard to tell apart not existing variables from variables set to null. This is most commonly used in testing array keys (for example, a database row set which can include null values).
use array_key_exists()
Post Reply