I'm new to PHP namespaces, what I have is:
namespace Foo\Bar;
class JsonAssetRest{
static function ini(){
$headers = getallheaders();
}
}
JsonAssetRest::ini();
And this is creating the error
Uncaught Error: Call to undefined function Foo\Bar\getallheaders() in /var/www/html/class JsonAssetRest.php
How do I use getallheaders() (the built in function) without getting this error?
Edit: The issue was related to removing a library while I was converting my code to a namespaced class. Said library defined getallheaders for nginx. I was confused by the error message adding namespacing and thought that was the issue.
Gonna leave this up in case someone else gets confused by the error while debugging. And because the comments have improved my understanding of namespacing in PHP.
Edit2: In case someone stumbles upon this error and wants to know how to solve the actual problem (getallheaders not being defined under nginx), it's been answered here: Get the http headers from current request in PHP
Global functions are available from any namespace. You do NOT need to add a \ prefix like the other answers suggest.
This error means that there is no function defined in the global or current namespace named getallheaders(). This function is an alias to apache_response_headers() which also likely doesn't exist. I'm assuming that PHP is not running as an apache module which is required for these functions.
By adding a backslash in front of the function like so: $headers = \getallheaders();
If you do not add this backslash in front of the function, it will assume that the function is in the same namespace as the class it is called from. Adding the backslash makes it so that it will look for that function in the global namespace, which is where the function lives.
Related
I seem to have some misconceptions on how autoloading works in PHP still, one I simply cannot explain.
I have a class called glue which has a spl_autoload_register within it's main function, here called run like so:
class glue{
public static function run(){
spl_autoload_register(array('glue','autoload'));
}
}
The autoload function works by loading via the PSR-0 standard and works from absolute paths. This is all tested as working etc. Note that glue is not namespaced.
The autoload function covers a namespace called glue. Within this namespace I have a error handler called \glue\ErrorHandler.
When I trigger an error the glue class will autoload \glue\ErrorHandler by PSR-0 notation from the root directory as defined by a stored ROOT constant. This has been tested as working as well in classes such as \glue\User and \glue\Session.
So now for the problem. I cause a Call-time pass-by-reference has been deprecated error within \glue\Validation and it doesn't seem to run my autoload function.
I can see how it is going into my autoload function for everything but when I call this error in that class it just seems to skip my autoloader and bail out saying it can't find my error handler class.
Normally I would say it is something with my programming but I have tried everything. I cannot explain how, for this one error. What compounds my confusion further is that if I cause a:
syntax error, unexpected T_ISSET in /media/server_ws/xxxxxxx/glue/Validation.php on line 47
Error it works. It seems to be for that one error it just will not autoload my error handler.
I thought this might be because my spl_autoload_register is not being binded to that namespace (since the error handler that works is actually called from within glue) and some how, maybe, it is randomly working. So from \glue\Validation I called a class I have never looked at: \glue\util\Crypt but that works and goes into the autoloader correctly.
When I call this error: Call-time pass-by-reference has been deprecated from within glue class it works perfectly.
Can anyone shed some light on this?
Edit
As requested here is a brievated version of Validation.php:
namespace glue;
use glue,
\glue\Exception,
\glue\Collection;
class Validation extends \glue\Component{
private function validateRule($rule){
// This is the line, notice the pass by reference down there?
$valid = $validator($field,$field_value,$params,&$this->model) && $valid;
}
}
The Call-time pass-by-reference has been deprecated error is thrown during script compilation, and auto-loading is disabled during compilation. It's disabled because the compiler cannot start compiling multiple scripts at the same time (i.e. it is not re-entrant), and auto-loading may load some script, which may require compiling it.
Source: https://github.com/php/php-src/blob/76ad52ccc501c02aeb068d2eb4f119ef6f0c2b6a/Zend/zend_execute_API.c#L1058
Deployed application to production and running into the following error on views that contain a call to a render function:
Fatal error: No matching function for overloaded 'render'
Example
/fuel/app/views/profile.php:
echo render('_validation');
Render is defined in /fuel/core/classes/view.php. The Autoloader should be making this available.
Ideas on environmental issues that may be causing this?
Edit: Both APPPATH and COREPATH hold the correct file paths
Try to use more clear function names, so you won't get in trouble with standart PHP functions.
It looks like your render-function is declared inside a class, if it is so you have to initialize an object of that class or use an existing object to call the method
echo $object->render('_validation');
Unsure if it is an issue specific with 5.3.3 but we just changed render() to View::forge() across the applications and all is well.
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 started to use the PHP __autoload function and now I'm getting those weird Fatal error: Cannot redeclare class xxx errors.
It's weird since these errors occur on classes I don't even load with the autoload function. And I also use require_once to include the files.
I'm really puzzled about this. Anyone knows anything about this kind of errors when using autoload?
require_once/include_once only looks at the file name when they're trying to include a file, not a class name. So you can have class Foo in both Foo.php and B.php, and then you'll get that error.
I'm not sure how __autoload would cause you any problems, unless __autoload requires Foo.php because it needs class Foo, and you require B.php manually which redefines class Foo.
By the way, use spl_autoload_register instead of __autoload.
i had same situation .. all i changed was and its working for me
include('xxx.php');
to
require_once('xxx.php');
I am not pretend on the best answer. Just my thoughts.
__autoload() is deprecated in PHP 7.2 and will be possiblly deleted.
I found this way to upload/include files
//initialize a function which will upload files
function upload(){//you can call the function as you like
//your path to files goes here
}
spl_autoload_register('upload')//specify the function, where you include your files(in this case it's upload function
I've had this before, not sure what caused it though. Make sure you're using require_once/include_once rather than the normal versions for starters. I think the problem was related to using class_exists without telling it to skip autoloading (class_exists($name, false)) - are you doing this?
I found the problem. Apparently when it wanted to include Bank class, it took the "bank.php" file from the current directory ^^. Which is just the bank page, it should have include "src/model/Bank.php". I removed the current directory from the search list and it has been fixed.
So always make sure the autoload function is including the correct files. Good practice is too name your files more straightforward like class.Bank.php or class.User.php instead of Bank.php or User.php.
Thanks for your help and quick response anyway!
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.