I'm currently integrating non symfony2 software (let's call it nsf) in an sf2 project. That software uses __autoload.
When trying to access some nsf features in a twig extension, I get fatal errors about classes not found. It appears that when called from symfony2 code, the __autoload function is not called at all.
I recently moved to php5 so this might sound like a newbie question but I'm trying to figure out what's going on.
Thanks for your clues.
This sounds like a problem originating in the usage of __autoload. If you can, replace those calls with the 'new' spl_autoload_register() call currently adviced:
see: http://php.net/manual/en/language.oop5.autoload.php
spl_autoload_register() provides a more flexible alternative for autoloading classes. For this reason, using __autoload() is discouraged and may be deprecated or removed in the future.
__autoload() is only one function, and is prone to overriding if 2 files want to do something with that. Using spl_autoload_register() means you can register several autoload functions.
Related
I have not installed or tinkered with Zephir yet.
Because before I do, I'd like to know whether it is possible to define PHP classes inside a Zephir extension that can only be instantiated by the extension itself but not in userland.
Sort of a friend or protected/private class perhaps, or maybe a class defined outside of the extension's namespace, or something similar. Preferably not an anonymous class, though.
I could have sworn some native PHP extensions have similar classes (not able to be instantiated in userland) as well, but it just so happens I can't find any example right now. Perhaps I have simply imagined this.
I'm writing a WordPress plugin. (However, this is not a WordPress-specific question - this challenge could arise in any PHP codebase which uses a plugin pattern.)
My plugin makes use of a popular third-party library, which is also used by a lot of other common WordPress plugins.
Obviously, if both my plugin and another plugin load their own copies of this library, PHP is going to throw an error, because I'm trying to redeclare an already-declared class.
How can I avoid this conflict? Before you answer, please consider why I've rejected these obvious options:
I could rename the library's classes, or put them in a new namespace. I don't like this because it involves modifying the library files. If I later need to upgrade to a newer version of the library, it would overwrite my modifications. And it's just generally an inelegant PITA.
Before my plugin actually includes the library, I could use class_exists() to make sure it hasn't already been included. There are two reasons I don't like this option:
Another plugin might use a different version of the library that has a slightly different API. This could cause my plugin, or the other plugin, to break (depending on which version of the library gets loaded first).
More importantly: the library in question contains multiple class definition files, and each child class includes its parent. Say that my plugin includes ChildClass1.php (which, in turn, includes BaseClass.php), and another plugin includes ChildClass2.php (which also includes its own copy of BaseClass.php). class_exists() doesn't help me here - there's no way that both plugins can include the ChildClasses they need without causing a conflict.
So: how can I make use of this library without running into one of these problems? Is there some way to override the library's namespace at include time (without modifying the library)? Is there some other solution that I'm overlooking? Seems like this must be a pretty common situation.
I'm answering my own question. (I can't believe I was this naïve only three years ago!)
This problem (among others) is exactly why dependency managers exist. (If you use npm, then you're already familiar with dependency management.)
In the PHP world, Composer is the standard tool for dependency management.
However, WordPress isn't really built to play nice with dependency managers (or with source control). In fact, WordPress actively fights against these practices.
There is a project called Bedrock, which tries to contort WordPress into something that's compatible with modern development practices. I haven't used it – but if you must use WordPress, it's worth investigating.
tl;dr:
The solution to this problem is to use a dependency manager, such as Composer.
But, WordPress simply isn't compatible with Composer – it'll fight you every step of the way, and you'll create more problems than you solve.
Unless you use Bedrock's version of WordPress – which is designed to work with Composer.
But, at that point, you might as well ditch WordPress, and adopt a CMS platform that's sanely engineered in the first place – and doesn't have to be twisted and tortured into cooperating with industry-standard practices.
I'm building an MVC framework and I was thinking that most of the classes used in the making of an application are models. So since I know that every model is inside a folder I could just use the native __autoload() function to implement a "feature" (that obliviously you can enable and disable as well) that automatically loads a model (Lazy programming).
Is it good or should I discard this idea? If the latter: why?
If you're building a PHP framework, it might be worth looking into the PSR-0 standard for autoloading. I'm afraid I don't know much about it, but I believe a number of substantial frameworks and libraries have agreed to abide by it for interoperability. I believe that would include Symfony2, Propel2 and the next major version of Zend Framework.
There is absolutely nothing wrong with relying on the __autoload() function, as long as you have a consistent naming scheme.
In fact, it's often better to use autoloading - it stops you from including classes "just in case" you use them.
From php.net:
In PHP 5, this is no longer necessary. You may define an __autoload() function which is automatically called in case you are trying to use a class/interface which hasn't been defined yet. By calling this function the scripting engine is given a last chance to load the class before PHP fails with an error.
Now I am wanting to know, is it bad practice to solely use __autoload to load the appropriate classes on a dynamic site?
The way my site is setup is to include files into the index.php file, for example http://www.site.com/index.php?p=PAGE-I-WANT-TO-LOAD
So if I am on the forums section or the blogs section of my site, I want only appropriate classes and functions to be loaded, so I use autoload but I never include a file manually, should I be using __autoload as a last resort or is what I am doing fine even on a high traffic system?
Bad? No. __autoload() is one of my favorite additions to PHP 5. It removes the responsibility (and annoyance) of manually having to include/require the class files necessary to your application. That being said, it's up to you as the developer to ensure that only the 'appropriate classes' are loaded. This is easily done with a structured naming scheme and directory structure. There are plenty examples online of how to properly use __autoload(), do a Google search and you'll find plenty of information.
Autoload is a good way to load only what classes is needed.
In PHP 5 >= 5.1.2, most of the problems with the old __autoload() dissapeared, thanks to spl_autoload_register().
Now I am wanting to know, is it bad practice to solely use __autoload to load the appropriate classes on a dynamic site?
Not at all. You can rely on autoload, all you need to do is to devise a good naming convention and implement an efficient autoloader.
There is one major issue to consider. Autoloading and Zend Guard do not play well together, because Zend Guard tends to rename things, which will mean that the naming convention you decided to use will most likely not be the same. If you will be using Zend Guard (or any other obfuscator for that matter) you will most likely be forced to include all the files by hand.
Here is a quote from the Zend Guard user guide:
Autoloading classes will not work since the filename on the disk would not
match the obfuscated class name.
The only danger to __autoload() is if you define a poor autoloading function. Generally, all you're going to get in terms of a performance hit is a few disk seeks as PHP looks for the right files that contain your classes. The upside is getting rid of all those annoying include() calls.
If you're worried about performance at this level, then you should already be using an opcode cache such as APC.
After inheriting some Zend Framework code it didn't work, after lots of fiddling I've managed to create the schema and rebuild the models, although now I'm getting the following error:
Call to undefined method Criteria::hasSelectClause() in home/richard/library/om/BaseDomainPeer.php on line 329
Why would propel generate files that call unknown methods?
I would think that you have a name collision and you load some other class called Criteria and you don't realize it because of autoloading. Try dumping the methods using get_class_methods()
Turns out the code was built on a system using the beta version of propel, when i forced my system to use the beta version, it worked.
to use the beta version, go here