SitePoint Sponsor

User Tag List

Page 1 of 4 1234 LastLast
Results 1 to 25 of 84
  1. #1
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Trouble in Zend Framework Land?

    I noticed this recently in Joshua Eichorn's blog ZActiverecord Can't Work and the comment by Mike Naberezny who seems to be involved in the implementation.

    The desire for static calls is interesting. I know it has been discussed here that static calls are not that desireable. It makes me wonder how thoughtful the peer review is.

    Beside that, there is definitely a sense that they are bumping up against the limitations of PHP. I wonder about ZController which has not been mentioned at all.

    Also note the framework-feedback@zend.com email address. Nothing to give feedback on yet, but there's an email address.
    Christopher

  2. #2
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yeah, I posted the debug_backtrace() hack as bit of a joke, not having seen Mike's comment. And lo and behold, seem they have thought of using something similar.

    Seems quite good thou Zend doing a framework, sometimes get the feeling alot of the PHP developers just develop the language, and do little in PHP itself.
    Probably an unfair comment, but does seem that way, when you hit some odd limitation you wonder why.

  3. #3
    SitePoint Addict
    Join Date
    Aug 2003
    Location
    Toronto
    Posts
    300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The desire for static calls is interesting. I know it has been discussed here that static calls are not that desireable. It makes me wonder how thoughtful the peer review is.
    ...or maybe it is a reflection of the thoughtfulness of the peer review here? Static calls are useful in many situations and like any other technique, involve trade-offs. Sure, they can be misused and then appear to be "undesirable" -- but so can any technique.

  4. #4
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    To say that there is trouble is an exaggeration; PHP is a dynamic language - there is always a solution

  5. #5
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ren
    Yeah, I posted the debug_backtrace() hack as bit of a joke, not having seen Mike's comment. And lo and behold, seem they have thought of using something similar.
    I saw that and I think it showed how far they have gone to try to make it work.

    Quote Originally Posted by Ren
    Seems quite good thou Zend doing a framework, sometimes get the feeling alot of the PHP developers just develop the language, and do little in PHP itself.
    Probably an unfair comment, but does seem that way, when you hit some odd limitation you wonder why.
    I get the sense that maybe one of the contributing companies had an ActiveRecord implementation that worked for them, so they got everyone excited. But when they actually tried to implement it without the constraints that the contributor had tolerated -- it is not working as well as planned.

    This all gives me some worries about the Controller architecture. I think it is the most critical part to make their framework actually work.
    Christopher

  6. #6
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    To say that there is trouble is an exaggeration; PHP is a dynamic language - there is always a solution
    Apparently it is going to have to continue to be dynamic to find a solution.
    Christopher

  7. #7
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I managed to solve this problem in my own framework, by using a little class I call "this"

    PHP Code:

    /**
     * Helper class for working with static method calls
     *
     * @package library
     */
    class this {
        
        
    /**
         * Returns the name of the class that called 'this'
         *
         * @return string
         */
        
    function class_name() {
            
    $trace debug_backtrace();
            
            foreach(
    $trace as $call) {
                if (isset(
    $call['class']) && $call['class'] != __CLASS__) {
                    return 
    $call['class'];    
                    
                }
            }
            
            return 
    false;
            
        }
        
        
    /**
         * Returns an array containing all the variables defined in the calling class
         *
         * @return array
         */
        
    function get_vars() {
            return 
    get_class_vars(this::class_name());
            
        }
        
        
    /**
         * Returns the value of a particular variable in the calling class. Returns
         * null if it doesn't exist
         *
         * @return mixed
         */
        
    function get_var($var_name) {
            
    $vars this::get_vars();
            
            if (isset(
    $vars[$var_name])) {
                return 
    $vars[$var_name];    
            } else {
                return 
    null;
            }
        }

        
    /**
         * Returns true if the variable exists in the calling class.
         *
         * @return bool
         */
        
    function var_exists($var_name) {
            
    $vars this::get_vars();
            
            return isset(
    $vars[$var_name]);
            
        }
        
        
    /**
         * Returns an array of all the methods defined in the calling class
         *
         * @return array
         */    
        
    function get_methods() {
            return 
    get_class_methods(this::class_name());    
            
        }
        
        
    /**
         * Returns true if the method exists in the calling class.
         *
         * @param string $method_name
         */
        
    function method_exists($method_name) {
            
    $methods this::get_methods();
            
            return 
    in_array($method_name$methods);
        }
        
        
    /**
         * Calls a static function in the calling class. All the parameters
         * are passed to the function, as in call_user_func
         *
         * @param string $method_name
         * @param mixed $args,...
         * @return mixed
         */
        
    function call($method_name) {
            
    $args func_get_args();
            
    array_shift($args);
            
            return 
    call_user_func_array(array(this::class_name(), $method_name), $args);
            
        }
        
        
    /**
         * Calls a static function in the calling class. The args array
         * is passed to the function, as in call_user_func_array
         *
         * @param string $method_name
         * @param array $args
         * @return mixed
         */    
        
    function call_array($method_name$args) {
            return 
    call_user_func_array(array(this::class_name(), $method_name), $args);
            
        }
        

    and a little test case
    PHP Code:
    class ThisTester extends UnitTestCase {

        var 
    $test 'hello';
        
        function 
    test_all() {
            
            
    $this->assertEqual(this::class_name(), __CLASS__);    
            
            
    $this->assertEqual(this::get_var('test'), 'hello');        

            
    $this->assertTrue(this::call('call_me'));

            
    $this->assertEqual(this::call('call_me''test'), 'test');
            
            
    $this->assertEqual(this::call('math'110100), 111);
            
            
    $this->assertEqual(this::call_array('math', array(220200)), 222);
            
            
    $this->assertTrue(this::method_exists('run'));
            
            
    $this->assertFalse(this::method_exists('foo'));
        }

        function 
    call_me($param true) {
            return 
    $param;    
        }
        
        
        function 
    math($one$two$three) {
            return 
    $one $two $three;
            
        }
        

    Usage should be clear, but here's some code from my finder method

    PHP Code:
                // find a single id                
                
    $options['conditions'] .= this::call('table_name').".".this::get_var('id_field')." = '".$ids[0]."'";
                
                
    $result this::call('find''all'$options); 
    Say what you will about using this kind of hack, "this" works

  8. #8
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees
    I managed to solve this problem in my own framework, by using a little class I call "this"
    That's actually very interesting. It's a hack, obviously, but are there any concrete drawbacks to the solution? Mainly, how fast is this::class_name() when it uses debug_backtrace() to do its thing?

  9. #9
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A quick benchmark using the following methods, the average of 10 000 calls each

    return __CLASS__: 0.025 ms
    return get_class($this): 0.037 ms
    return this::class_name(): 0.214 ms

    so it's an order of magnitude slower, but it's still a miniscule amount. I have yet to find a significant drawback, in any case.

  10. #10
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi.

    SimpleTest uses a similar hack to get the location of the test failure. Every single assertion calls this method, but everything seems to run fast enough.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  11. #11
    SitePoint Enthusiast
    Join Date
    Jul 2004
    Location
    Finland
    Posts
    73
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Maybe i'm just stupid, but how does this differ from just using __CLASS__?

    PHP Code:
    class this {
        
    /**
         * Returns the name of the class that called 'this'
         *
         * @return string
         */
        
    function class_name() {
            
    $trace debug_backtrace();
            
            foreach(
    $trace as $call) {
                if (isset(
    $call['class']) && $call['class'] != __CLASS__) {
                    return 
    $call['class'];    
                    
                }
            }
            
            return 
    false;
            
        } 


    PHP Code:
    class base{
        

       static function 
    run() {
         
          echo  
    this::class_name();
          echo 
    __CLASS__;
            
        }     
        
    }
    class 
    test extends base{
        
    }
    base::run();
    test::run(); 
    outputs:
    basebasebasebase

    php version 5.1

    It clearly isn't solution for that particular problem stated in first post.

  12. #12
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't program in PHP5, but in PHP4 your code outputs:

    basebasetestbase

    I can't see why it wouldn't do the same under PHP5, I'll have a look at home tonight.

  13. #13
    SitePoint Enthusiast
    Join Date
    Jul 2004
    Location
    Finland
    Posts
    73
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is interesting, I tried it in php4 and it really does work. In php 5 backtrace does contain only class where called function is defined, not the class where it was called from.

  14. #14
    SitePoint Guru
    Join Date
    May 2003
    Location
    virginia
    Posts
    988
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That's too bad. I was hoping I could start using static finders! That's the neastest "hack" I've seen in a while.

  15. #15
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I imagine that if you remove the static keyword, it would work, although it would through an E_STRICT error.

  16. #16
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Apparently it is going to have to continue to be dynamic to find a solution.
    I'm sure PHP will cope with the demands of modern day web development

  17. #17
    SitePoint Guru
    Join Date
    Jun 2004
    Location
    Finland
    Posts
    703
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees
    I imagine that if you remove the static keyword, it would work, although it would through an E_STRICT error.
    No, it does not work (PHP 5.5.1).

  18. #18
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Sorccu
    (PHP 5.5.1).
    Christopher

  19. #19
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees
    I imagine that if you remove the static keyword, it would work, although it would through an E_STRICT error.
    Nah, doesnt seem to work in PHP 5.1.2 RC.

  20. #20
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It could be that they changed debug_backtrace() so that it shows the class the contains the method rather than the class that was called. I'll look into it tonight and see if I can find another way of making it work.

  21. #21
    SitePoint Guru
    Join Date
    Jun 2004
    Location
    Finland
    Posts
    703
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arborint
    Umm Oh well. I meant PHP 5.1.1, obviously

  22. #22
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I did some research, the debug_backtrace() behavior was changed in 5. I'm curious to know how Zend plan on working around this issue; are they going to give up on the static call route, or are they going to add something to the language to support it?

  23. #23
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees
    I did some research, the debug_backtrace() behavior was changed in 5. I'm curious to know how Zend plan on working around this issue; are they going to give up on the static call route, or are they going to add something to the language to support it?
    I get the impression they'd like todo both, so ZPF is compatable with 5.01, but have some C solution for future versions.

    Can't see how they're going to get it working suitably with 5.01 thou, grepping the source isn't a good solution, slow and would prevent distributing encoded source.

  24. #24
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I suppose the easiest thing for them to do would be to support two syntaxes. As far as a C solution, all that would be needed is a constant similar to __CLASS__, but that gives you the name of the class that was called (like __CALLED_CLASS__ ).

    In any case, I find it amusing that they did the webcast using that syntax, while there is currently no way of implementing it in PHP5. Makes you wonder how much code they'd actually written at that point.

  25. #25
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees
    In any case, I find it amusing that they did the webcast using that syntax, while there is currently no way of implementing it in PHP5. Makes you wonder how much code they'd actually written at that point.
    It certainly mirrors the experience in several threads here (e.g. Container, DI and Persistence) where we started out very excited and eventually ground to a halt -- with a rich understanding of the subject, no doubt -- but frustrated that no clean, complete implementation was available.
    Christopher


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •