I get this error when trying to autoload classes - php

I get this error when trying to autoload classes.
I declare this class in myclass.php file and instantiate it in test.php. but i got class not found error on xammp. Is _autoload function case sensitive in php.
class MyClass {
//some properties and methods
}
function __autoload($class_name) {
require_once($class_name.".php");
}
$myclass = new MyClass();
Anyone know what the problem is?

Make sure you define MyClass correctly in your myclass.php.Your problem is not caused by __autoload because the error is class not found instead of file not found which require_once would throw out if it fails.

Class names and function names in PHP are not case-sensitive, but your autoloader must use the correct case when using require* or include* because your OS filesystem may be case-sensitive. And if your autoloader uses relative paths, make sure the classes invoked are in PHP's include_path.

Related

Using namespaces in PHP

I am working on the AWS documentation which uses Guzzle framework. I have to deal with namespaces here and I am not able to get it working. I went through the docs and examples and understood that we can have packages for projects using namespaces.
I went ahead and tried a simple example, but unsuccessful. Here's the example: this is the index.php:
use My\Full\Classname as Another; //Also tried use My\Full\Classname
$obj = new Another; //with $obj = new Classname;
echo $obj->add();
I have Classname.php in the directory structure like this My->Full->Classname.php:
<?php
class Classname{
public static function add(){
return 2+2;
}
}
?>
I am trying to call the function in index.php but getting error:
Fatal error: Class 'Another' not found in C:\wamp\www\guzzleEx\index.php on line 19
which is the line where I instantiate the Classname object $obj = new Another;
What is the mistake i am making? Is there any INI that needs to be updated or any other config issue? How can I make the code working? If you use the normal include for Classname.php it works fine.
Namespaces need to be explicitly declared, they do not come from a certain directory structure.
So if you do not have a line that reads namespace My\Full; in front of your class Classname, then your class is not in any namespace, but in the root namespace.
Thus you cannot use it as \My\Full\Classname, but \Classname or even Classname directly.

spl_autoload Class not found following namespaces directory structure

I'm trying to use class autoloading in my project. This is what I wrote:
on main.php:
namespace myproject;
spl_autoload_extensions(".php");
spl_autoload_register();
subspace\myclass::mystaticmethod();
on subspace/myclass.php:
namespace myproject\subspace;
class myclass {
static function mystaticmethod() {
....
}
}
I get this error:
PHP Fatal error: Class 'myproject\\subspace\\myclass' not found
So far I've only found a problem with case sensitive names in the documentation, so I switched to lowercase only but I get the same error. Why?
[EDIT] Using PHP 5.3.3
I've found the problem: The default include directory would be the full namespace/subspace path.
I've also found a good solution. From http://www.php.net/manual/en/function.spl-autoload.php#92767:
<?php
// Add your class dir to include path
set_include_path(get_include_path().PATH_SEPARATOR.'..');
// Make autoloader look for commonly used "myclass.php" type filenames
spl_autoload_extensions('.php');
// Use default autoload implementation
spl_autoload_register();
?>
The default autoload implementation is written in C and is always slightly faster than a PHP one.

autoload and namespace

Suppose I have classes in same namespaces:
directory :
(folder) a
a.php
(folder) b
b.php
c.php
and we use namespace and __autoload as you see:
in folder b\b.php :
<?php
namespace b;
use b as x;
function __autoload($clsName){
$clsName='../'.str_replace('\\', '/', $clsName).'.php';
require_once $clsName;
}
class b{
function __construct(){
print("b file<hr/>");
}
}
$t=new x\c(); // line 13
?>
and in folder b\c.php :
<?php
namespace b;
class c{
function __construct(){
print("c file<hr/>");
}
}
?>
when we define $t=new x\c, __autoload doesn't call!
please help me :(
error message:
Fatal error: Class 'b\c' not found in C:\xampp\htdocs\project\TEST\b\b.php on line 13
You have not defined autoloader. PHP looks for __autoload (or \__autoload - function defined in global namespace) while you have defined only \b\__autoload (yes, functions are namespaced to!)
How to fix it: move __autoload declaration outside namespace
Better fix: you should use spl_autoload_register
It's hard to see exactly what is going wrong. By the looks of the error, it appears that the __autoload() function isn't being called. If it was I would expect the require_once statement to fail with an error saying file not found, or something like that.
You could try by putting some debugging statements in your __autoload() function to see what's going on, including a var_dump of your $clsName variable.
It might be worth noting the following message that appears in the PHP manual regarding autoloading:
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.
You should also note, that there is a "standard" for PHP autoloading, called PSR-0. Here is a link to an article that gives a good explanation of it.
In both the article and the PSR-0 document mentioned above, are example autoloaders that you can use. I would suggest using one of these than trying to implement your own.

Capital letters in class name PHP

I have two classes in my system. One is called file and second is File.
On my localhost when i instantiate file i get file object, but my friend running the same script gets object of File like the capital letters were unrecognized and "file" was equal to "File".
Is that some configurable thing?
We are both running on Windows. I have WampServer, he has XAMPP.
PHP is case insensitive for the class naming. it means you can normally do $file = new file() even if the class is named File and vice-versa.
Are you by any chance relying on the auto loading of class files ? If this is the case, it is possible that depending on the computer, the interpreter don't always find the same file first. This will explain the problem.
I strongly suggest that you rename your classes. It's always a bad idea to rely on case to differentiate two different things and by convention, class names always start with a capital letter.
If you can't change the class names, I suggest to have a look at php namespaces.
Classnames in PHP are not case sensitive (that doesn't depend on the operating system)
class myclass {}
$x = new MYclaSS;
var_dump($x);
object(myclass)#1 (0) {
}
so as general advice: You shouldn't start and try to mix something there :)
Code like this should not work:
class ab {}
class AB {}
Fatal error: Cannot redeclare class AB in ... on line x
I guess you are using some kind of lazy loading for class files, may be you are programming in a PHP framework. The secret will lie in your __autoload function. Find it.
Check PHP manual for Autoloading.
The following code:
<?php
class file {
public $a;
}
class File {
public $a2;
}
$x = new file();
Gives an error: Cannot redeclare class File so again, the trick might be which file is included.
Behavior of your code displays that one of the classes isn't being loaded (otherwise you'll see class redeclare error). It is probably the auto loader that first loads the file class and then when it finds definition to File it simply assumes that that it has already loaded the class (due to case insensitive behavior of PHP).

PHP Fatal error: Cannot redeclare class

Does anyone know what can cause this problem?
PHP Fatal error: Cannot redeclare class
You have a class of the same name declared more than once. Maybe via multiple includes. When including other files you need to use something like
include_once "something.php";
to prevent multiple inclusions. It's very easy for this to happen, though not always obvious, since you could have a long chain of files being included by one another.
It means you've already created a class.
For instance:
class Foo {}
// some code here
class Foo {}
That second Foo would throw the error.
That happens when you declare a class more than once in a page.
You can fix it by either wrapping that class with an if statement (like below), or you can put it into a separate file and use require_once(), instead of include().
if (!class_exists('TestClass')) {
// Put class TestClass here
}
Use include_once(); - with this, your codes will be included only one time.
This will happen if we use any of the in built classes in the php library. I used the class name as Directory and I got the same error. If you get error first make sure that the class name you use is not one of the in built classes.
This error might also occur if you define the __construct method more than once.
Sometimes that happens due to some bugs in PHP's FastCGI.
Try to restart it. At Ubuntu it's:
service php-fastcgi restart
I had the same problem while using autoload like follows:
<?php
function __autoload($class_name)
{
include $class_name . '.php';
}
__autoload("MyClass1");
$obj = new MyClass1();
?>
and in other class there was:
namespace testClassNamespace;
class MyClass1
{
function __construct()
{
echo "MyClass1 constructor";
}
}
The sollution is to keep namespace compatibility, in my example namespace testClassNamespace; in both files.
Just adding;
This error can also occur if you by mistake put a function inside another function.
PHP 5.3 (an I think older versions too) seems to have problem with same name in different cases. So I had this problem when a had the class Login and the interface it implements LogIn. After I renamed LogIn to Log_In the problem got solved.
Just do one thing whenever you include or require filename namely class.login.php. You can include it this way:
include_once class.login.php or
require_once class.login.php
This way it never throws an error.
This function will print a stack telling you where it was called from:
function PrintTrace() {
$trace = debug_backtrace();
echo '<pre>';
$sb = array();
foreach($trace as $item) {
if(isset($item['file'])) {
$sb[] = htmlspecialchars("$item[file]:$item[line]");
} else {
$sb[] = htmlspecialchars("$item[class]:$item[function]");
}
}
echo implode("\n",$sb);
echo '</pre>';
}
Call this function at the top of the file that includes your class.
Sometimes it will only print once, even though your class is being included two or more times. This is because PHP actually parses all the top-level classes in a file before executing any code and throws the fatal error immediately. To remedy this, wrap your class declaration in if(true) { ... }, which will move your class down a level in scope. Then you should get your two traces before PHP fatal errors.
This should help you find where you class is being included from multiple times in a complex project.
Did You use Zend Framework? I have the same problem too.
I solved it by commenting out this the following line in config/application.ini:
;includePaths.library = APPLICATION_PATH "/../library"
I hope this will help you.
Another possible culprit is source control and unresolved conflicts. SVN may cause the same class to appear twice in the conflicted code file; two alternative versions of it ("mine" and "theirs").
I have encountered that same problem:
newer php version doesn't deal the same with multiple incluse of the same file (as a library), so now I have to change all my include by some include_once.
Or this tricks could help, if you d'ont have too much class in your library...
if( class_exists('TestClass') != true )
{
//your definition of TestClass
}
I had the same problem "PHP Fatal error: Cannot redeclare class XYZ.php".
I have two directories like controller and model and I uploaded by mistakenly XYZ.php in both directories.(so file with the same name cause the issue).
First solution:
Find in your whole project and make sure you have only one class XYZ.php.
Second solution:
Add a namespace in your class so you can use the same class name.
It actually means that class is already declared in the page and you are trying to recreate it.
A simple technique is as follow.
I solved the issue with the following. Hope this will help you a bit.
if(!class_exists("testClassIfExist"))
{
require_once("testClassIfExist.php");
}
i have encountered that same problem. found out the case was the class name. i dealt with it by changing the name. hence resolving the problem.
You must use require_once() function.

Categories