Asked  7 Months ago    Answers:  5   Viewed   30 times

Sorry if this is basic, I am trying to learn as much as I can about OO in PHP and I am slowly learning how to use it (very limited).

So I am wanting to know if __autoload() has any affect on PHP opcode cache's?

 Answers

67

(Disclaimer : I only know APC)

What an opcode cache do is :

  • when a file is included/required, it take the full path to that file
  • check if the opcodes corresponding to that file are already in RAM (in opcode cache)
    • if yes, return those opcode so they are executed
    • if no, load the file and compile it to opcodes ; and store opcodes in cache.

The important point, here, is the entry point : the full path to the file.


What autoloading generally do is :

  • get the name of a class
  • transform it to the name of a file
  • include/require that file

So, the informations that are relevant for the opcode cache (full path to the file, and the fact that it is included/required) are still here.

In consequence, autoload shouldn't bring any trouble with op code caching.

(And, when using APC, it doesn't, as far as I can tell)

Wednesday, March 31, 2021
 
nomie
answered 7 Months ago
17

Well, at first. You need to tell the autoloader where to find the php file for a class. That's done by following the PSR-0 standard.

The best way is to use namespaces. The autoloader searches for a Acme/Tests/ReturningTest.php file when you requested a AcmeTestsReturningTest class. There are some great namespace tutorials out there, just search and read. Please note that namespacing is not something that came into PHP for autoloading, it's something that can be used for autoloading.

Composer comes with a standard PSR-0 autoloader (the one in vendor/autoload.php). In your case you want to tell the autoloader to search for files in the lib directory. Then when you use ReturningTest it will look for /lib/ReturningTest.php.

Add this to your composer.json:

{
    ...
    "autoload": {
        "psr-0": { "": "lib/" }
    }
}

More information in the documentation.

Now the autoloader can find your classes you need to let PHPunit know there is a file to execute before running the tests: a bootstrap file. You can use the --bootstrap option to specify where the bootstrap file is located:

$ ./vendor/bin/phpunit tests --bootstrap vendor/autoload.php

However, it's nicer to use a PHPunit configuration file:

<!-- /phpunit.xml.dist -->
<?xml version="1.0" encoding="utf-8" ?>
<phpunit bootstrap="./vendor/autoload.php">

    <testsuites>
        <testsuite name="The project's test suite">
            <directory>./tests</directory>
        </testsuite>
    </testsuites>

</phpunit>

Now, you can run the command and it will automatically detect the configuration file:

$ ./vendor/bin/phpunit

If you put the configuration file into another directory, you need to put the path to that directory in the command with the -c option.

Wednesday, March 31, 2021
 
codingb
answered 7 Months ago
76

I had same problem with PDO::nextRowset(), as it returns true even there is no more rowsets available, therefore when calling fetchAll(), it raises exception HY000. (tested on PHP 5.5.12 windows, Mysql 5.5.17 linux)

A workaround for this problem is to check number of columns with method PDO::columnCount() before fetching rowset. If it is non-zero, you have a valid rowset, and thus you could call PDO::fetchAll().

Even if PDO::nextRowset() reports true, columnCount() will report number of columns before moving to next rowset.

Example:

while ($objQuery->columnCount()) {
    $tab[] = $objQuery->fetchAll(PDO::FETCH_ASSOC);
    $objQuery->nextRowset();
}
Wednesday, March 31, 2021
 
motanelu
answered 7 Months ago
23

Here's the only right answer.

Every namespace needs its own spl_autoload_register() function.

also, spl_autoload_register() syntax changed in 5.3:

spl_autoload_register(__NAMESPACE__ . "\className::functionName"));

The following should work:

namespace glue;

require_once 'import.php';

use glueimport as import;
use gluecorerouter as router;

$import = new import();

spl_autoload_register(__NAMESPACE__ . "\$import::load"));

/** Works and echos gluerouter **/
$router = new router();

/** Don't do nothing **/
$cheese = gluecommonis_email($email);

Here is some live code that Just works!

in ../WebPageConsolidator.inc.php:

class WebPageConsolidator
{
    public function __construct() { echo "PHP 5.2 constructor.n"; }
}

in test.php:

<?php

namespace WebPage;

class MyAutoloader
{
    public static function load($className)
    {
        require '../' . __NAMESPACE__ . $className . '.inc.php';
    }
}

spl_autoload_register(__NAMESPACE__ . "\MyAutoloader::load");

class Consolidator extends WebpageConsolidator
{
    public function __construct()
    {
        echo "PHP 5.3 constructor.n";

        parent::__construct();
    }
}

// Output: 
// PHP 5.3 constructor.
// PHP 5.2 constructor.

So I know it works.

Wednesday, July 28, 2021
 
leebriggs
answered 3 Months ago
64

There seems to still be confusion about this topic, however in most cases it comes down to ease vs performance.

A good mailing list thread to read would be this one on Zend Frameworks mailing list:

http://n4.nabble.com/ZF-and-Autoloading-td640085i20.html

Now, the correlation is here because if you inherit from not-yet-defined class, you might rely on autoload to define it (though you might also rely on include), and actually the presence of the autoload facility may encourage you to use such inheritance. But this is not the autoload which brings trouble (see after Ramus' "it's not just autoload" in the blog for some examples of troublesome things). So the right phrase would be "people which tend to rely on autoload tend also to use code which defies compile-time binding". Which can't be seen as autoload fault, of course, and just avoiding autoload won't help a bit with that - you would also have to rewrite your code so that compile-time binding could happen. And it has nothing to do with uses of autoload with "new", for example.

As for the slowdown from the effects described above - i.e., absence of the compile-time binding - the code indeed becomes a bit slower and such code can lead in some obscure cases to some trouble to opcode caches (not in the autoload cases - but in cases where classes are defined inside conditions, or, God forbid, different definition is created depending on condition) - but it has next to nothing to do with using autoload by itself. The amount of slowdown, however, seem to be greatly exagerrated by people - it is nothing (and I repeat to be clear - NOTHING) compared to the performance benefit given by the opcode cache due to the absence of the disk operations and compilation stage. You could probably compose an artificial benchmark that would show some significant slowdown, but I do not believe any real application would even notice.

source: http://n4.nabble.com/ZF-and-Autoloading-td640085i20.html#a640092

Friday, July 30, 2021
 
Desmond Hume
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :