PHP Instanciation and late static binding context
Asked Answered
C

1

2

Short version

This code $out = new static(); makes PHP to quit unexpectedly and silently, using either xampp or wampserver in Windows.

Long version

I'm working on an old project which runs flawlessly on ubuntu 15.10 with NGinX/php-fpm php5.5.9 (dev) and also on Ubuntu 14.04 with apache2.4/Fast-CGI php5.5.13 (production).

Today, a designer colleague of mine just checked out this same repo to edit some html/css.
Unfortunately he hasn't been able to run the project using either Xampp:v3.2.2 (PHP 5.5.38) or Wampserver:2.5 (PHP 5.5.13) on his windows 10 desktop.

The code implements an old home brewed (active record like) database abstraction layer, in which all tables are represented with a class. Every class inherits from the Table class.
PHP stops on the following snippet (located in the "Table" class) :

# Table.php
public static function Get($id = null){
    echo 'test'; # Displays in the web browser
    error_log('test'); # append a line in the error_log file
    $out = new static(); # php seams to stop here
    echo 'after'; # Not displayed
    error_log('test'); # Not inserted in the log file
    // Fetch data from DB if id is specified
    if($id){
        $out->load($id);
    }
    return $out;
}

He then tried to replace the static call with:

// …
$class = get_called_class();
echo $class; # Displays "Article" (the right class name) in the browser
$out = new $class(); # The script dies silently as before.
// …

It looks like something is going wrong with PHP object instantiation in a late static binding context on windows.
Huge thank's to whom may help fix this.

Celanese answered 25/10, 2016 at 13:19 Comment(11)
Please enable error reporting (beginning of the first file set:) error_reporting(E_ALL); ini_set('display_errors', true);Canister
@DanFromGermany Error_reporting is already enabled in php.ini and its value is E_ALL error_reporting=E_ALL. display_errors is also uncommented and activated display_errors=On.Celanese
So, what is the error ( in log files, something ) ? :DLunitidal
@RăducanuIonuţ I'm sorry but no error gets dumped into the error_log file :(Celanese
As far as I was aware static was a keyword that you could not use as a class name until PHP7 See php.net/manual/en/reserved.keywords.php and even PHP7 does not like itButylene
@Butylene Thank you for pointing this out, I will have a look. But the thing is, this code has been working for months now under php >= 5.3 < php 5.6 :|Celanese
yea, wierd I knowButylene
Maybe look at the code that is actually running and not the code in the repo. Just maybe they are not quite in line as of course we would all expect that they shoud beButylene
@Butylene git diff is empty, caches have been purged. Nothing changes. Call stack checked, the code executed definitely seams to be the one from the repo. :|Celanese
Yea, but there is no Guarantee that the code running live is actually the code that is stored in the repo. Check the REAL live codeButylene
Let us continue this discussion in chat.Celanese
L
0

Show full code demonstrating the issue. Seems to work for me with PHP 5.3.0 or newer: https://3v4l.org/83ost

<?php

class MyTest
{
    protected $x = "";
    
    protected function __construct($x)
    {
        $this->x = $x;
    }
    
    public static function staticFactoryNew()
    {
        static $counter = 1;
        return new static($counter++);
    }
    
    public function identify()
    {
        echo "Instance of MyTest #".($this->x)."\n";
    }
}

class MyInheritedTest extends MyTest
{
    function foo()
    {
        echo "OK";
    }
}

$t1 = MyInheritedTest::staticFactoryNew();
$t2 = MyInheritedTest::staticFactoryNew();

$t1->identify();
$t2->identify();

$t1->foo();
Leake answered 31/3, 2023 at 14:17 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.