I'm trying to include a custom path to a certain file using php's set_include_path. Here's the code:
file.php
<?php
$path = 'classes/';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
$obj = new MyClass();
$obj->methodCall();
?>
Here's my root directory structure
www
|_webapp
|_classes
|_MyClass.php
|_nbproject
|_file.php
All I get when I execute the script is this error message: Fatal error: Class 'MyClass' not found in C:\wamp\www\webapp\file.php. I have tried including the file using require and it works but I have hit a wall with set_include_path. Does anybody know what I can do about this?
Thanks
You're adding a relative path to the global include path. Is that what you intended?
You are possibly not including the file where class MyClass is defined. set_include_path() allows to omit the path in the require_once statement, not to omit the statement itself.
I have the impression that the tool you have in mind is class autoloader.
You choose include method like this format include 'path/filename.php'
Related
So I am learning PHP MVC for the first time, and i came up to a term - autoloading all the required .php files.
So I searched the web for some examples, and made an autoload file with spl_autoload_register method, calling an anonymous method to require_once all needed files. I don't know what is wrong, but it seems not to work.
So the spl_autoload_register method I made is:
spl_autoload_register(function($className){
if(is_file('libraries/' . $className . '.php')){
echo 'libraries/' . $className . '.php';
require_once 'libraries/'. $className . '.php';
}
});
File structure in the project is available here: https://prnt.sc/gPaVkLZRsPpj
If I comment out the spl_autoload_register method and require all the necessary files one by one, it is working perfectly fine.
require_once 'libraries/Core.php';
require_once 'libraries/Controller.php';
require_once 'libraries/Database.php';
The file in which I'm trying to do the autoload looks like this:
<?php
require_once '../app/autoload.php';
// Init Core.php
$init = new Core();
And the error message I get is:
Fatal error: Uncaught Error: Class "Core" not found in C:\xampp\htdocs\farkops-mvc\public\index.php:5 Stack trace: #0 {main} thrown in C:\xampp\htdocs\farkops-mvc\public\index.php on line 5
I have searched trough the internet, tried other implementations of spl_autoload_register but they all don't work.
Can someone please help me to resolve this issue? :)
So the problem was (as #Lawrence Cherone mentioned in comments), that autoloader was called in context to the current working directory, in which the file that was calling that autoloader was located.
So I made a few changes.
Made an constant APPROOT, that contains link to app folder (the root folder for all core files)
define('APPROOT', dirname(dirname(__FILE__)));
In my case, APPROOT is C:\xampp\htdocs\mvc\app
Used that constant to get the right directory with autoloader:
spl_autoload_register(function($className){
if(is_file(APPROOT . '/libraries/' . $className . '.php')){
require_once APPROOT . '/libraries/' . $className . '.php';
}
});
And now, autoloader can access filer in folders like
C:\xampp\htdocs\mvc\app\libraries\Core.php without any errors.
I want to use the autoloader in my php project and I don't know if my file organization is viable. Right now my folder is structured this way :
-ProjectFolder
index.php
-common
-ajax
ajax_file.php
-classes
MyClass.php
In MyClass.php I have the following line of code namespace common\classes;.
In index.php I have
spl_autoload_register(function ($class_name){
$file = str_replace('\\', '/', $class_name);
require "$file.php";
});
And so I can call in the index.php file the "test" static method by having the following line in my code :
common\classes\MyClass::test();
But index.php is used get answers from ajax_file.php.
If I just call my "test" method by just adding the same line of code into ajax_file.php it tells me that the class can't be found. I guess that it's because it's loaded independently from what's going on in index.php.
I don't know how I can access MyClass from ajax_file.php and I'm not even sure it's possible since I've read some things that seem to indicate it's not possible to "go back" using "../" with the autoloader.
Could you tell me what's the good way do this ?
You have to make sure that your autoloader uses absolute and not relative paths.
This involves defining a base directory for the root namespace corresponding to projectFolder.
In index.php:
spl_autoload_register(function ($class_name) {
$file = __DIR__ . '/' . str_replace('\\', '/', $class_name);
require "$file.php";
});
You have some examples of autoloader on php-fig to comply with the standard (PSR-4).
Note that the ajax_file.php file must explicitly include the autoloader (and therefore index.php)
I got a problem with php and OOP.
I tried to create a object and inside the object I tried to load data from mysql.
My files are build like this.
HTML
|_ php
|__ objects
|_ content
In object folder is the object file "Event". The object created in a script in php folder and the whole script is called from a html file in content.
My Problem is, that i use the object from different locations. And the include_once method wont work.
event.php:
<?php
include_once(ROOT.'php/db.inc.php');
class Pb1_event
{
public $ev1_id;
// do something
}
I also tried it with include_once('./../db.inc.php');.
How should I include it ? Is it a good way to include it in this file or should I include it anywhere else ?
Firstly what I would do is use either __DIR__, or better is $_SERVER['DOCUMENT_ROOT'] for absolute pathing. These are constants that will refer to your server web root. Assuming it refers to the root directory you have given to us, you would do:
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/db.inc.php';
But to gain a better understanding, you should echo it and see how your directory paths. Also, for the "best practices" you should use autoloading, you can read more about it here:
http://php.net/manual/en/language.oop5.autoload.php
Define an autoload function and have it call the file you need, for example, if you need a class called DB your function might look something like this:
function __autoload($class) {
if ($class == 'DB') {
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/db.inc.php';
}
}
Use __FILE__ or __DIR__ magic constants:
include_once(dirname(__FILE__) . '/../db.inc.php');
include_once(__DIR__ . '/../db.inc.php');
My suggestion would be to register an autoloader in the beginning of your scripts using spl_autoload_register():
spl_autoload_register(function ($className) {
include 'path/to/php/objects/' . $className . '.php';
});
When you want to instantiate an object, where ever you are, you just need to do:
$myclass = new MyClass();
The autoloader will load the correct class. All you need to think about is to call the files in "objects" the same as your classes. Example:
class Pb1_event {
}
filename: path/to/php/objects/Pb1_event.php
you can try this for your warning:
include_once($_SERVER["DOCUMENT_ROOT"].'/php/db.inc.php');
I am trying to upgrade the code of a new project I am working on to comply with PSR-0.
I am using and SPL loader class, However I may be doing something wrong, I just can't spot what the issue is.
I keep getting the following error:
Fatal error: Class 'widezike\General' not found in /nfs/c03/h04/mnt/169128/domains/widezike.com/html/beta/lib/functions.php on line 14
This is my folder structure:
index.php
-lib
config.php
init.php
spl-class-loader.php
functions.php
-widezike
-General.php
This is my functions file where it begins anything to do with the server side code:
<?php
include 'init.php';
include 'config.php';
include 'spl-class-loader.php';
$loader = new SplClassLoader('General', 'lib/widezike');
$loader->register();
use widezike\General;
//Run the output buffer
General::ob();
So this is my code for now, but I can't seem to find what's causing the fatal error...
Thanks in advance
I'm taking a bit of a guess here but I think the issue is in the constructor..
$loader = new SplClassLoader('General', 'lib/widezike');
In the code you linked to they are the namespace and the include path.
Play around with those until it works is all I can suggest.
You might try:
$loader = new SplClassLoader(null, 'lib');
Or
$load = new SplClassLoad('General', 'lib');
On the other hand I personally just use a very simple spl_autoload_register function to do my class loading for me..
spl_autoload_register(function($class){
$filename = str_replace('\\', '/', $class) . '.php';
require($filename);
});
$object = new phutureproof\common\whatever();
I would then have a file /phutureproof/common/whatever.php with the contents:
<?php
namespace phutureproof\common;
class whatever
{
}
I realised that the issue was that my name spaces were wrong, so if you have the same issue just check and make sure that your namespaces are correct!
I'm playing around with the SPL autoload functionality and seem to be missing something important as I am currently unable to get it to work. Here is the snippet I am currently using:
// ROOT_DIRECTORY translates to /home/someuser/public_html/subdomains/test
define('ROOT_DIRECTORY', realpath(dirname(__FILE__)));
define('INCLUDE_DIRECTORY', ROOT_DIRECTORY . '/includes/classes/');
set_include_path(get_include_path() . PATH_SEPARATOR . INCLUDE_DIRECTORY);
spl_autoload_extensions('.class.php, .interface.php, .abstract.php');
spl_autoload_register();
When I echo get_include_path() I do get the path I expected:
// Output echo get_include_path();
.:/usr/lib/php:/usr/local/lib/php:/home/someuser/public_html/subdomains/test/includes/classes/
However when I run the code I get this error message:
Fatal error: spl_autoload() [function.spl-autoload]: Class Request could not be loaded in
/home/someuser/public_html/subdomains/test/contact.php
on line 5
Request.class.php is definitely in the /home/someuser/public_html/subdomains/test/includes/classes/ directory.
What am I missing?
There is a comment (anonymous) on http://www.php.net/manual/en/function.spl-autoload-register.php#96804 that may apply to your problem: spl_autoload_register() doesn't seem to play nice with camelcase, and in your case could be trying to find request.class.php instead of Request...
The path where the class is supposed to be seems not to match the path were you expect them. Compare
.:/usr/lib/php:/usr/local/lib/php:/home/someuser/public_html/subdomains/test/includes/classes/
with
/home/someuser/public_html/subdomains/test/
The difference is, that your class is not in includes/classes/ as your SPL requires it but a few directories above.
I got a similar error message but my issue was different. My error message looked like
PHP Fatal error: spl_autoload(): Class Lib\Lib\Regex could not be loaded in /dir1/dir2/lib/regex.php on line 49
It turned out I forgot to remove the Lib\ from Lib\Regex inside the Regex class definition itself. I had something like the following:
namespace Lib;
class Regex {
...
public static function match($pattern, $str) {
$regex = new Lib\Regex($pattern);
...
}
}