Let's say I've got two files class.php and page.php
class.php
<?php
class IUarts {
function __construct() {
$this->data = get_data('mydata');
}
}
?>
That's a very rudamentary example, but let's say I want to use:
$vars = new IUarts();
print($vars->data);
in my page.php file; how do I go about doing that? If I do include(LIB.'/class.php'); it yells at me and gives me Fatal error: Cannot redeclare class IUarts in /dir/class.php on line 4
You can use include/include_once or require/require_once
require_once('class.php');
Alternatively, use autoloading
by adding to page.php
<?php
function my_autoloader($class) {
include 'classes/' . $class . '.class.php';
}
spl_autoload_register('my_autoloader');
$vars = new IUarts();
print($vars->data);
?>
It also works adding that __autoload function in a lib that you include on every file like utils.php.
There is also this post that has a nice and different approach.
Efficient PHP auto-loading and naming strategies
In this case, it appears that you've already included the file somewhere. But for class files, you should really "include" them using require_once to avoid that sort of thing; it won't include the file if it already has been. (And you should usually use require[_once], not include[_once], the difference being that require will cause a fatal error if the file doesn't exist, instead of just issuing a warning.)
Use include_once instead.
This error means that you have already included this file.
include_once(LIB.'/class.php');
use
require_once(__DIR__.'/_path/_of/_filename.php');
This will also help in importing files in from different folders.
Try extends method to inherit the classes in that file and reuse the functions
Use include("class.classname.php");
And class should use <?php //code ?> not <? //code ?>
Related
I am working on an application where i have quite a lot of PHP Classes and i write classes like below
<?php
if(!class_exists('AClass1')){
class AClass1{
}
}
?>
and likewise i have around 400 classes and also i use a php autoloader script
https://github.com/varunsridharan/php-autoloader
Along with a classmap generator
https://github.com/varunsridharan/php-classmap-generator
So what happens is that when i write a condition like below
if(class_exists('AClass1')){
// Some Code To RUN
}
In the above code if the class AClass1 not exists then it autoloads via class_exists function which is good for me
But when i write a code like this in a file called aclass1.php
<?php
if(!class_exists('AClass1')){
class AClass1{
}
}
?>
and if that file is loaded via above if condition then after loading the file it still loops into autoloader instead it just should register the class
so whats the good way to avoid looping into autoloader even if the file inside class source
Never use class_exists when registering a class
use class_exists('CLASSNAME',false) to avoid looping inside autoloader
I wrote a simple test to see if a include loop might exists:
test.php
<?php
// The simpliest autoloader
spl_autoload_register(function ($class) {
include __DIR__ . '/Hello.php';
});
if (class_exists('Hello')) {
$hello = new Hello();
exit('class exists');
} else {
exit('class does not exists');
}
Hello.php
<?php
if (!class_exists('Hello')) {
class Hello {
}
}
I put both these files in the same folder. Then I run:
php test.php
There is no error or loop. It simply prints:
class exists
But frankly, you do not need the class_exists check in your class file at all if you're using an autoloader. The autoloader would only be called if the class is not already exists in the current environment. So unless you would manually include a class file after it is autoloaded, you'll be fine.
If for some strange reason you might have that, use include_once instead of include.
I have a Problem developing in PHP. First I have to say that I'm not the experienced PHP developer on this Planet.
My Code/Problem is as followed:
In file Controllers\TestController.php:
<?php
namespace My\Test\Controllers;
class TestController
{
public function HelloTest()
{
echo 'Hello!';
}
}
?>
When I want to include this class in another php file like this
File Models\TestModel.php:
<?php
namespace My\Test\Models;
use My\Test\Controllers;
class TestModel
{
public function TestModelFunction()
{
$control = new TestClass();
$control->HelloTest();
}
}
?>
File index.php_
<?php
use My\Test\Models;
$model = new TestModel();
$model->TestModelFunction();
?>
That just won't work... I'll always get the following error:
Class 'TestModel' not found!
When I now add:
include_once 'Models/TestModel.php' in index.php
AND
include_once '..Controllers/TestController.php' in TestModel.php
then it works...
Folder Structure:
Project
|-Models
| TestModel.php
|-Controllers
| TestController.php
|index.php
But do I really have to specify every Time where the files are?
Yes you will always have to include the files that define your classes.
The namespace is just a way to package your classes together, not a way to automatically include PHP files.
If your are looking for a way to automatically include PHP files when needed, have a look on autoload.
Namespaces logically separate code into different... well, namespaces. It has nothing to do with including the files that contain code for that namespace. So yes, you do need to include the file in some way or another (e.g. autoloaders) in addition to namespacing them.
Another approach is to use autoloader (http://php.net/manual/en/language.oop5.autoload.php). You can find some good open source autoloaders out there.
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.
I have a user authentication system that I am currently writing. Problem is, I don't want to have to include class x,y,z,etc for every page that I want to use that class for. For example, here is the index page:
///////// I would like to not have to include all these files everytime////////
include_once '../privateFiles/includes/config/config.php';
include_once CLASSES.'\GeneratePage.php';
include_once DB.'\Db.php';
include_once HELPERS.'\HelperLibraryUser.php'; //calls on user class
//////////////////////////////////////////////////////////////////////////////
$html = new GeneratePage();
$helper = new HelperLibraryUser("username","password","email");
$html->addHeader('Home Page','');
$html->addBody('homePage',
'<p>This is the main body of the page</p>'.
$helper->getUserEmail().'<br/>'.
$helper->doesUserExists());
$html->addFooter("Copyright goes here");
echo $html->getPage();
As you can see, there are a few files that I need to include on every page, and the more classes I add, the more files I will have to include. How do I avoid this?
You can define an autoload function, e.g.:
function __autoload($f) { require_once "/pathtoclassdirectory/$f.php"; }
This way, when php encounters a reference to a class it doesn't know about, it automatically looks for a file with the same name as that class and loads it.
You could obviously add some logic here if you need to put different classes in different directories...
Make a file called common.php and put these include statements as well as any other functions/code that you need in every file (such as database connection code, etc) in this file. Then at the top of each file simply do this:
<?
require_once('common.php');
This will include all your files without having to include them seperately.
It is highly recommended not to use the __autoload() function any more as this feature has been DEPRECATED as of PHP 7.2.0. Relying on this feature is highly discouraged.. Now the spl_autoload_register() function is what you should consider.
<?php
function my_autoloader($class) {
include 'classes/' . $class . '.class.php';
}
spl_autoload_register('my_autoloader');
// Or, using an anonymous function as of PHP 5.3.0
spl_autoload_register(function ($class) {
include 'classes/' . $class . '.class.php';
});
?>
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.