Reputation: 69
Hey guys before I begin my question, I'm gonna paste a photo of my folders structure so it will be easier to visualize.
Okay so, in the header.php
highlighted above, I have this line of code:
<?php require_once("admin/admin_pages/includes/init.php"); ?>
And in that init.php file:
<?php
require_once("functions.php");
require_once("db_config.php");
require_once("database.php");
require_once("user.php");
require_once("session.php");
require_once("photo.php");
require_once("db_object.php");
?>
However, when I try to open the index.php
file located in my root directory it gives this error:
The init.php that's being required_once
is working. However it doesn't seem to find the files(which are in the same directory as the init.php) that are required in the init.php
file itself. Why is this happening?
Note: All the paths work when I am playing around in my admin/admin_pages/index.php
page.
EDIT: This is a screenshot of the contents in my includes folder.
<?php
//Just in case an includes file is not called in the init.php file.
function classAutoloader($class)
{
$class = strtolower($class);
$path = "includes/{$class}.php";
if (file_exists($path)) {
require_once($path);
} else {
die("The file named {$class}.php was not found.");
}
}
spl_autoload_register('classAutoloader');
function redirect($location)
{
header("Location: {$location}");
}
?>
EDIT: This is what is giving the error message FYI. I have setup an autoloader function. However, the file is not missing and should be loaded either way.
Upvotes: 1
Views: 3008
Reputation: 9
Put the db_object.php file above the users.php file in the init.php file and it will be found. I'm working on the same course and thats the solution
Upvotes: 0
Reputation: 7485
This isn't an answer, but may help:
Consider the following.
If we have three files in the same directory:
a.php:
<?php
require_once 'b.php';
require_once 'c.php';
b.php:
<?php
class B extends C
{}
c.php:
<?php
class C
{}
If I run a.php I get this output:
Fatal error: Class 'C' not found in /var/www/stackoverflow/req_test2/b.php on line 3
This shows that order matters with require calls.
If I swap out the contents of a.php for the following and run it:
<?php
spl_autoload_register();
$b = new B;
var_dump($b);
I get this output:
object(B)#1 (0) {
}
spl_autoload_register() without parameters here uses the default implementation of spl_autoload(): a reference to a class named Foo, will look to include a file foo.php from your include path.
The initialisation of B here references class C, and the autoloader above will take care of requiring the appropriate files as needed.
I'd recommend placing each class definition in a file of its own. With a one-one mapping of filename to class. You may also be interested in the PSR-4 style.
Declare your autoloader early. Utility functions can also be included upfront.
A fix for your code would be to add your includes folder to your include path, and to change your require line to $path = "{$class}.php";
. I would personally remove the die line within your autoloader, as you may need to register more than one autoloader - these are stackable as are your include paths.
Upvotes: 0
Reputation: 69
Hey guys thank you all for your input. I have finally found the problem with my code. It is not because of the autoloader function.
I did not know that the order of the files being called in the init.php
mattered. I have simply re-ordered the require_once()
statements.
The db_object.php
file is actually the file that contains the parent class for my objects (photos and users). The photo.php
and users.php
contain inherited classes from the db_object.php
. Which would made sense on why we need to find the db_object.php
first.
Before:
<?php
require_once("functions.php");
require_once("db_config.php");
require_once("database.php");
require_once("user.php");
require_once("session.php");
require_once("photo.php");
require_once("db_object.php");
?>
After:
<?php
require_once("functions.php");
require_once("db_config.php");
require_once("database.php");
require_once("db_object.php");
require_once("user.php");
require_once("session.php");
require_once("photo.php");
?>
Upvotes: 0
Reputation: 878
Since you've made some edits, in which you've presented us -- among other things -- with the existence of an autoloader, I've re-read your question. Two important things that jump out:
index.php
located in the root of your website.classAutoloader()
.admin/admin_pages/index.php
.)It would seem that this is still a path issue similar to the one mentioned below. When the autoloader is called from ~/index.php
it's checking whether your root contains includes/db_object.php
and that's not the case.
You can fix this by specifying the path to your includes folder relative to the autoloader file, something like this:
$path = __DIR__ ."/path/to/includes/{$class}.php";
Although I don't see any problems with this solution, it doesn't look very elegant to me. Alternatively you could specify the path from your root.
By requiring admin/admin_pages/includes/init.php
you're running the code in init.php
from the file that's requiring it. If that makes sense. You could write the following in header.php
and it would behave the same as requiring init.php
:
<?php
require_once("functions.php");
require_once("db_config.php");
require_once("database.php");
require_once("user.php");
require_once("session.php");
require_once("photo.php");
require_once("db_object.php");
?>
You may notice that that wouldn't make sense, since those paths aren't correct when called from header.php
. You can fix this by using the __DIR__
constant:
The directory of the file. If used inside an include, the directory of the included file is returned. This is equivalent to dirname(FILE). This directory name does not have a trailing slash unless it is the root directory. ~ The Manual
With the aforementioned information you could probably figure it out yourself, but to make my answer complete, change the code in init.php
to:
<?php
require_once __DIR__ . "/functions.php";
require_once __DIR__ . "/db_config.php";
require_once __DIR__ . "/database.php";
require_once __DIR__ . "/user.php";
require_once __DIR__ . "/session.php";
require_once __DIR__ . "/photo.php";
require_once __DIR__ . "/db_object.php";
?>
Note that:
require_once
isn't a function but a statement, so you call it as such. The same goes for require
, include
and include_once
.db_object.php
fails... That seems kinda strange.Pro-tip (as mentioned in the comments by AnyhonyB):
One of the biggest annoyances is having to write a long list of needed includes at the beginning of each script (one for each class).
In PHP 5, this is no longer necessary. The spl_autoload_register() function registers any number of autoloaders, enabling for classes and interfaces to be automatically loaded if they are currently not defined. By registering autoloaders, PHP is given a last chance to load the class or interface before it fails with an error. ~ The Manual
Upvotes: 1