Reputation: 16065
I am currently testing some code in cmd, and I'm experiencing some problems with relative paths.
It is clearly visible that the path is set correctly, furthermore it works as expected under http protocol. I assume there's something that's blocking relative paths in cmd, because if I replace that with an absolute path the file gets included. This however is not efficient as filesystems may change and the use of relative paths is a must. I'm really bad with OS stuff so I guess I shouldn't be making any more assumptions. Thanks!
EDIT: Mind = Blown
Upvotes: 2
Views: 2348
Reputation: 158250
Basics:
When called from HTTP the working directory of index.php
is C:\xampp\htdocs\actualframework\public\
when called from command line (in your example) it is C:\xampp\php
. So the script tries to include C:\xampp\Framework/class/routers/System.php
which isn't there.
You need to utilize the __DIR__
constant in order to make the require command working independently from where index.php
was called:
require(__DIR__ . "/../Framework/class/routers/System.php");
__DIR__
points to the directory where the source file is located which is using the __DIR__
constant, in your example: C:\xampp\htdocs\actualframework\public\
Using include_path
Another good idea is to utilize the include_path
directive in order to make the real location of a library file transparent to the application. This will give you more freedom when you once change the directory layout. include_path
is a configuration value that can be set in php.ini
or in scripts and contains a list od directories where php should look if you pass relative paths to require
or include
as well as some functions like file_get_contents()
, fopen()
, ...
Configure the include path on top of your index.php
(or in a separate bootstrap.php
which gets included):
ini_set('include_path', implode(PATH_SEPARATOR, array(
__DIR__ . '/../Framework/class',
__DIR__ . '/../Framework/interface',
// add the existing value at the end
ini_get('include_path')
)));
Now you can use paths like this to require classes:
require_once 'System.php';
require_once 'routers/Foo.php';
Autoloading
Since PHP5 there is a feature called autoloading
which eases the including of classes. Autoloading basically provides the ability to define a hook function which gets called every time a class is accessed which has not been defined before. Imagine you have the following files:
lib/Person.php
<?php
class Person {
... some code
}
index.php
<?php
$hek2mgl = new Person();
Normally this code will trigger an error because Person
is accessed without including lib/Person.php
before. This is the point where autoloading can be used. Lets see how a simple autoload method can look like in this (simple example):
function autoload($classname) {
$path = __DIR__ . "/lib/$classname.php";
if(file_exists($path)) {
require_once $path;
}
}
You need to reqister the autoloader using spl_autoload_register()
. index.php
can look like this:
<?php
// define simple autoloader for project
function autoload($classname) {
$path = __DIR__ . "/lib/$classname.php";
if(file_exists($path)) {
require_once $path;
}
}
// register autoloader
spl_autoload_register('autoload');
// will work now
$hek2mgl = new Person();
If you ask me, autoloading is one of the coolest things in PHP5. You can refine the autoload method in order to work with the include_path
directive. Doing so it gets easy to work with a couple of libraries without taking care about where they are physically stored in filesystem. You may give my Jm_Autloader
a try, the code is on github and you can install it using PEAR or composer.
Upvotes: 7
Reputation: 1346
As @hek2mgl points out, it has to do with the current working directory being wrong.
In your case the working directory is c:/xampp/php/
but it should be c:/xampp/htdocs/actualframework/public/
.
There's at least two solutions to fix this, the most obvious one being changing the working directory on the command line:
cd c:/xampp/htdocs/actualframework/public/
c:/xampp/php/php.exe index.php
Alternatively you can set the current working directory from your PHP script by adding the following into your index.php
before you try to include/require
anything:
chdir(realpath(dirname(__FILE__)));
Upvotes: 5