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 this is not your bug, you can add a comment by following this link.
If this is your bug, but 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

Add a Patch

Pull Requests

Add a Pull Request

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-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 21:01:36 2024 UTC