SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Member
    Join Date
    Sep 2004
    Location
    Hanoi
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    A static method call to the parent method

    I have got a strange case that can be described as follows:

    (PHP 5.1)
    Code:
    <?php
    class Test {	
    	public function callMe() {
    	echo $this->Me();	//line 4
    	}	
    	public function Me() {
    		return "Me";
    	}	
    }
    
    class TestChild extends Test {	
    	public static function callParent() {		
    		parent::callMe();
    	}	
    }
    
    TestChild::callParent(); //line 17
    ?>
    It returns:

    Fatal error: Using $this when not in object context in D:\webroot\php\Test.php on line 4

    I understand that the call TestChild::callParent(); will not make any instance of the class Test. Therefore, $this->Me() make nonsense.

    But the only thing I am confused here is the way PHP notifies the position that generates the error: line 4. Actually, the line 17 generates the error. The warning from PHP compiler makes me hard to debug.

    Can it be treated a bug in PHP?

  2. #2
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pcdinh
    But the only thing I am confused here is the way PHP notifies the position that generates the error: line 4. Actually, the line 17 generates the error. The warning from PHP compiler makes me hard to debug.

    Can it be treated a bug in PHP?
    No, because it gives you a correct message: the error was thrown at line 4, not at line 17 -- if there wasn't any error at 4, you wouldn't get an error message.

    In situations like that you need debug_backtrace() or, as I do, install xdebug extensions which pretty-prints the backtrace on every error message.

  3. #3
    SitePoint Enthusiast
    Join Date
    Nov 2005
    Location
    Norway
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    When it is clearly line 4 that generates the error, why should it be an error? You are calling the parent::callMe() at line 17, but that's not very callMe() is defined, and that's the function where the error resides. Else, you'd need to trace the stack to find out where the error was.

  4. #4
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Both the error and the error notification demonstrate correct behaviour. Find the "err, where is this error actually generated?" -stuff hard to debug? Me too. This is great for that:
    PHP Code:
    /**
     * Error handler, providing rigorous backtrace information.
     * @param    int        error type
     * @param    string    error message
     * @param    string    file name
     * @param    string    line number
     */
    function ErrorHandler ($error_type$error_message$file$line)
    {
        static 
    $error_types = array
            (
                
    1        => 'E_ERROR',            2        => 'E_WARNING',
                
    4        => 'E_PARSE',            8        => 'E_NOTICE',
                
    16         => 'E_CORE_ERROR',        32        => 'E_CORE_WARNING',
                
    64         => 'E_COMPILE_ERROR',    128        => 'E_COMPILE_WARNING',
                
    256        => 'E_USER_ERROR',        512        => 'E_USER_WARNING',
                
    1024    => 'E_USER_NOTICE',        2047    => 'E_ALL',
                
    2048    => 'E_STRICT'
            
    );
        
        
    // Check error type against error reporting level. @ is always ignored.
        
    if (($error_type != 0) && ($error_type ini_get('error_reporting')))
        {
            echo    
    "<strong>".$error_types[$error_type]."</strong>: ".$error_message."<br />\n",
                
    "In <strong>".$file."</strong> ",
                
    "on line <strong>".$line."</strong><br />\n",
                
    "<p>Backtrace:</p><pre>";
            
            
    $backtrace debug_backtrace();
            
    // First is always ErrorHandler, skip it
            
    array_shift($backtrace);
            
    $i = -1;
            foreach (
    $backtrace as $trace)
            {
                
    $args = array();
                if (isset(
    $trace['args']))
                {
                    foreach (
    $trace['args'] as $a)
                    {
                        switch (
    gettype($a))
                        {
                            case 
    'integer':
                            case 
    'double':
                                     
    $args[] = $a;
                            break;
                            case 
    'string':
                                    
    $a htmlspecialchars(substr($a064))
                                        .((
    strlen($a) > 64) ? '&hellip' '');
                                    
    $args[] = "\"$a\"";
                            break;
                            case 
    'array':
                                    
    $args[] = 'Array('.count($a).')';
                            break;
                            case 
    'object':
                                    
    $args[] = 'Object('.get_class($a).')';
                            break;
                            case 
    'resource':
                                    
    $args[] = 'Resource('.strstr($a'#').')';
                            break;
                            case 
    'boolean':
                                    
    $args[] = $a 'True' 'False';
                            break;
                            case 
    'NULL':
                                    
    $args[] = 'NULL';
                            break;
                            default:
                                    
    $args[] = 'UNKNOWN';
                        }
                    }
                }
                
                echo    
    '#'.++$i.' ',
                    
    $trace['file'].'('.$trace['line'].'): ',
                    (isset(
    $trace['class'])    ?    $trace['class'].$trace['type']    :    ''),
                    
    $trace['function'].'('.implode(', ',$args).')',
                    
    "\n";
            }
            echo 
    '#'.++$i.' {main}</pre>';
        
            exit;
        }
    }

    set_error_handler        ('ErrorHandler'); 

  5. #5
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, if you've got a fatal it's a bit too late to backtrace...

  6. #6
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog
    Well, if you've got a fatal it's a bit too late to backtrace...
    A slight setback, yes.


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
  •