php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52396 Acessing a class within a static class
Submitted: 2010-07-22 00:42 UTC Modified: 2010-07-24 12:58 UTC
From: mark at rwrightson dot f9 dot co dot uk Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 5.3.2 OS: Windows 7
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: mark at rwrightson dot f9 dot co dot uk
New email:
PHP Version: OS:

 

 [2010-07-22 00:42 UTC] mark at rwrightson dot f9 dot co dot uk
Description:
------------
It is currently not possible to access a class that is instantiated within another class that is instantiated within a static object variable.

Using the example below I would expect this line of code to function correctly:
(where self is Foo)
self::$bar->test->hello();

however this isn't the case.  A getter must be created in the bar() class to get the test class object variable.  I.e. getTest().  The above line can then be re-written as :

self::$bar->getTest()->hello();

this works correctly.  In finding this solution I also tried the same concept in another OO language (Java).  I copied the code as per below and altered the syntax.  the line above became: bar.test.hello(); which worked ok.  

For this reason, as the operation discussed here is a standard OO concept, it could be classed as a bug within PHP.

The attached test script demonstrates the getTest() workaround.  commented out above this line are numerous error messages that I encountered when trying to access the test class.

Many Thanks

Test script:
---------------
	 

<?php

echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"    \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">
  <head>
    <title>XHTML-document
    </title>
  </head>
  <body>";

  new foo();
  
echo"</body>
</html>";

class foo
{
    public static $bar;
    public static $foo2;
   
    public function __construct()
    {
        echo"<code>construct foo</code>";
        echo"<p>create static instance of bar</p>";
        self::$bar = new bar();
        echo"<p>call hello() in bar class</p>";
        self::$bar->hello();
        echo"<p>call hello() in test class from Foo class through bar class</p>";
//N.B. The following methods failed.  However there is one solution...

//self::$bar->$test->hello();
//Notice: Undefined variable: test in ... on line...
//Fatal error: Cannot access empty property in ... on line...

//self::$bar->test->hello();
//Notice: Undefined property: bar::$test in ... on...
//Fatal error: Call to a member function hello() on a non-object in ... on...

//self::$bar::$test->hello();
//Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in ... on...
              
//self::$bar::test->hello();
//Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in ... on...        

//self::$bar->self::$test->hello();
//Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in ... on... 

//self::$bar::self::$test->hello();
//Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in ... on... 
        
        self::$bar->getTest()->hello();
        echo"<p>create static instance of foo2</p>";
        self::$foo2 = new foo2();
    }
}
class bar
{
    //N.B. the class Test() can be instantiated as either a static or a normal variable
    //public static $test;
    public $test;
     
    
        public function __construct(){
        echo "<code>construct bar</code>";
        echo"<p>create static instance of test class in bar class </p>";
        //self::$test = new test();
        $this->test = new test();
        
        }
        
        public function hello(){
        echo"<code>class:foo function:hello()</code>";
        }
        public function getTest(){
          //echo"getanother";
          //return self::$test;
          return $this->test;
        }
}
class test{
  public function __construct(){  
    echo "<code>construct test</code>";
  }
  
  public function hello(){  
    echo "<code>class:test function:hello()</code>";
  }
}
class foo2
{
  
    public function __construct()
    {
        echo"<code>construct foo2</code>";
        echo"<p>call hello() in foo2 class</p>";
        foo::$bar->hello();
    }
    
    public function hello(){
      echo"class:foo2 function:hello";
    }
}
  ?>

Expected result:
----------------
construct foo

create static instance of bar
construct bar

create static instance of test class in bar class
construct test

call hello() in bar class
class:foo function:hello()

call hello() in test class from Foo class through bar class
class:test function:hello()

create static instance of foo2
construct foo2

call hello() in foo2 class
class:foo function:hello()

Actual result:
--------------
same as above.  the code demonstrates a work around to the problem.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-07-23 12:20 UTC] aharvey@php.net
-Status: Open +Status: Bogus
 [2010-07-23 12:20 UTC] aharvey@php.net
Closing, because I can't reproduce this. Even if I uncomment the right
line in your example, that is:

self::$bar->test->hello();

It appears to do what it's supposed to. I've put a much simpler version
of what I think your problem is up at http://codepad.viper-7.com/l2GN2F
and that also works normally.

Also, please note that we'd really prefer reproduce code that's no more
than about 20 lines -- I had a fair job trying to follow what was going
on in your code. :)
 [2010-07-24 12:58 UTC] mark at rwrightson dot f9 dot co dot uk
Apologies for posting long code here.

The code aharvey posted doesn't demonstrate the problem.
I have added a small amount of extra code to his code to demonstrate the exact issue.
http://www.voltnet.co.uk/phperror/52396.txt

I should probably mention that this example doesn't work on php 5.2.9 but it does work on php v5.3.2

The code should output:
"ClassThatPrintsItsName hello"
If line 41 is commented out and replaced with line 42 the following error will appear:
Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in C:\htdocs\error.php on line 41.

Looking at the two lines below, the problem that is occurring is when trying to statically access a static variable within a class that has already been statically accessed.
$c::$bar::$another->hello();        //this line won't work
$c::$bar->getAnother()->hello();    //this line will work

The line (line 41) that won't work can be rewritten as:
$a = $c::$bar;
$a::$another->hello();
and this will make it work

I hope this better demonstrates the issue
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Wed Feb 05 13:01:33 2025 UTC