How can I connect php files from different folders in php? - php

Can you help me connect my php files from different folders..
I have a main folder sample then inside it I have 2 folders naming 0lib and Portal.
Inside the folder 0lib there is folder amazon and inside it there are folders Mock, Model, Samples and some php files like Client.php , Model.php
Inside the folder Portal I have the productFeed.php
I already connect those files using include() and require(). I also use autoload Class... They seems ok but when I run it the error says...
Fatal error: Class 'amazon_Client' not found in /var/www/html/sample/0lib/amazon/Samples/SubmitFeedSample.php on line 68
The SubmitFeedSample.php is inside the folder 0lib->amazon->Samples->SubmitFeedSample.php
Here is my autoload Class codes:
function __autoload($className){
$filePath = str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
$includePaths = explode(PATH_SEPARATOR, get_include_path());
foreach($includePaths as $includePath){
if(file_exists($includePath . DIRECTORY_SEPARATOR . $filePath)){
require_once $filePath;
return;
}
}
}
I think the auto load is the problem here.

I got your function to work as is by making one change:
function __autoload($className){
$filePath = str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
$includePaths = explode(PATH_SEPARATOR, get_include_path());
foreach($includePaths as $includePath){
// Assign the compiled file path here
if(file_exists($classdir = $includePath . DIRECTORY_SEPARATOR . $filePath)){
// Don't use $filePath but rather newly assigned $classdir
require_once($classdir);
return;
}
}
}
EDIT:
The function works, but I think you are missing the relative (or absolute) path. Try creating a config.php file that you can include on all your pages that will set the root path:
root/config.php
define("ROOTDIR",__DIR__);
spl_autoload_register('__autoload');
root/some/document.php
include_once(__DIR__.'/../config.php');
$test = new test_Test();
function.__autoload()
function __autoload($className)
{
$filePath = str_replace('_',"/",$className).'.php';
// This would yield something like:
// /data/19/2/133/150/2948313/user/3268049/htdocs/mydomain/test/Test.php
$classdir = ROOTDIR."/".$filePath;
if(file_exists($classdir)) {
require_once($classdir);
return;
}
}
test_Test Class:
This class would need to be here: ROOTDIR.'/test/Test.php'

Related

Invisible autoloading in PhilePhP

I was just going through the code of PhileCMS and came across the following lines of code:
if (Registry::isRegistered('Phile_Settings')) {
$config = Registry::get('Phile_Settings');
if (!empty($config['base_url'])) {
return $config['base_url'];
}
}
The file can be seen HERE
How come the static method of class Registry can be used here, when the file is not included or required at all? Is there some kind of auto loading going on in the backend that can't be seen? If so, what is this new kind of auto loading mechanism that has emerged?
Read more about of classes autoloading in PHP: http://php.net/manual/en/language.oop5.autoload.php
In PhileCMS the classes autoloading is confugired in the Phile\Bootstrap::initializeAutoloader() method (copy-paste of method body from the github for convinience):
spl_autoload_extensions(".php");
// load phile core
spl_autoload_register(function ($className) {
$fileName = LIB_DIR . str_replace("\\", DIRECTORY_SEPARATOR, $className) . '.php';
if (file_exists($fileName)) {
require_once $fileName;
}
});
// load phile plugins
spl_autoload_register('\Phile\Plugin\PluginRepository::autoload');
require(LIB_DIR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php');
https://github.com/PhileCMS/Phile/blob/master/lib/Phile/Bootstrap.php#L93

PHP autoloader - $classname includes the entire folder path and not just the class name itself?

I am following WordPress's naming convention where a class My_Class should reside in the file named class-my-class.php. I used this autoloader for WordPress, written by Rarst. If I print out the $class_name variable, I see that the prefix class is appended to the folder name and not the class file. I had the same issue with some other autoloader I used earlier. I can do a little bit of string manipulation and get what I want but I want to know what is the exact issue.
What could be wrong?
I just had a look at this autoloader you linked to, I would say it should be on line 21 something like this :
$class_path = $this->dir . '/class-' . strtolower( str_replace( '_', '-', basename( $class_name ) ) ) . '.php';
basename takes only the file part + file extension of the path.
You need also to check where this autoloader file is, because $this->dir is set to DIR, which is the directory where the autoloader file is.
Use a flexible loader.
try this one.
function TR_Autoloader($className)
{
$assetList = array(
get_stylesheet_directory() . '/vendor/log4php/Logger.php',
// added to fix woocommerce wp_email class not found issue
WP_PLUGIN_DIR . '/woocommerce/includes/libraries/class-emogrifier.php'
// add more paths if needed.
);
// normalized classes first.
$path = get_stylesheet_directory() . '/classes/class-';
$fullPath = $path . $className . '.php';
if (file_exists($fullPath)) {
include_once $fullPath;
}
if (class_exists($className)) {
return;
} else { // read the rest of the asset locations.
foreach ($assetList as $currentAsset) {
if (is_dir($currentAsset)) {
foreach (new DirectoryIterator($currentAsset) as $currentFile) {
if (!($currentFile->isDot() || ($currentFile->getExtension() <> "php")))
require_once $currentAsset . $currentFile->getFilename();
}
} elseif (is_file($currentAsset)) {
require_once $currentAsset;
}
}
}
}
spl_autoload_register('TR_Autoloader');

__autoload() not being called?

I'm using the Amazon Payments PHP SDK and the __autoload() is working fine in the browser but when I switch to my CLI scripts it just doesn't seem to be calling the function.
All I'm getting is "PHP Fatal error: Class 'OffAmazonPaymentsService_Client' not found".
I've put debugging into the __autoload() function to echo out the function being called and the file paths and nothing is printed in the terminal, just in the browser.
I've done a print_r(get_defined_functions()); and __autoload() is listed after the require_once() of the file it's in and is not listed before so I know it's getting the right function.
I've also checked the include_path being set and it's in the root of the Amazon Payments source folder which is where it should be so there's no reason why it wouldn't find the class OffAmazonPaymentsService_Client if __autoload() is called.
Can anyone advise why __autoload() isn't working in CLI? I'm not executing with php -a...
I have replaced the __autoload() within the AmazonPayments PHP SDK with spl_autoload_register() and that has worked.
/*
function __autoload($className){
$filePath = str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
$includePaths = explode(PATH_SEPARATOR, get_include_path());
foreach($includePaths as $includePath){
if(file_exists($includePath . DIRECTORY_SEPARATOR . $filePath)){
require_once $filePath;
return;
}
}
}
*/
spl_autoload_register(function($className){
$filePath = str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
$includePaths = explode(PATH_SEPARATOR, get_include_path());
foreach($includePaths as $includePath){
if(file_exists($includePath . DIRECTORY_SEPARATOR . $filePath)){
require_once $filePath;
return;
}
}
});

what is the usage of `spl_autoload_extension() `with `spl_autoload_register()`?

I am using spl_autoload_register() function to include all files . What i want that any class having extension .class.php or .php would includes directly. I made below class and register two different function and everything working fine, BUT
I think there is some way so that i need to register only one function to include both extensions together.
please have a look on my function and tell me what i am missing
my folder structure
project
-classes
-alpha.class.php
-beta.class.php
-otherclass.php
-includes
- autoload.php
-config.inc.php // define CLASS_DIR and include 'autoload.php'
autoload.php
var_dump(__DIR__); // 'D:\xampp\htdocs\myproject\includes'
var_dump(CLASS_DIR); // 'D:/xampp/htdocs/myproject/classes/'
spl_autoload_register(null, false);
spl_autoload_extensions(".php, .class.php"); // no use for now
/*** class Loader ***/
class AL
{
public static function autoload($class)
{
$filename = strtolower($class) . '.php';
$filepath = CLASS_DIR.$filename;
if(is_readable($filepath)){
include_once $filepath;
}
// else {
// trigger_error("The class file was not found!", E_USER_ERROR);
// }
}
public static function classLoader($class)
{
$filename = strtolower($class) . '.class.php';
$filepath = CLASS_DIR . $filename;
if(is_readable($filepath)){
include_once $filepath;
}
}
}
spl_autoload_register('AL::autoload');
spl_autoload_register('AL::classLoader');
Note : there is no effect on line spl_autoload_extensions(); . why?
i also read this blog but did not understand how to implement.
There is nothing wrong with the way you do it. Two distinctive autoloaders for two kinds of class files are fine, but I would give them slightly more descriptive names ;)
Note : there is no effect on line spl_autoload_extensions(); . why?
This only affects the builtin-autoloading spl_autoload().
Maybe it's easier to use a single loader after all
public static function autoload($class)
{
if (is_readable(CLASS_DIR.strtolower($class) . '.php')) {
include_once CLASS_DIR.strtolower($class) . '.php';
} else if (is_readable(CLASS_DIR.strtolower($class) . '.class.php')) {
include_once CLASS_DIR.strtolower($class) . '.class.php';
}
}
You may also omit the whole class
spl_autoload_register(function($class) {
if (is_readable(CLASS_DIR.strtolower($class) . '.php')) {
include_once CLASS_DIR.strtolower($class) . '.php';
} else if (is_readable(CLASS_DIR.strtolower($class) . '.class.php')) {
include_once CLASS_DIR.strtolower($class) . '.class.php';
}
});
Maybe this will help:
http://php.net/manual/de/function.spl-autoload-extensions.php
Jeremy Cook 03-Sep-2010 06:46
A quick note for anyone using this function to add their own autoload
extensions. I found that if I included a space in between the
different extensions (i.e. '.php, .class.php') the function would not
work. To get it to work I had to remove the spaces between the
extensions (ie. '.php,.class.php'). This was tested in PHP 5.3.3 on
Windows and I'm using spl_autoload_register() without adding any
custom autoload functions.
Hope that helps somebody.

Namespace usage in object orientated style PHP

I have been fiddling around with Namespace in PHP and was trying to make it work, but it fails
Let me show the example code:
test\views\classes\MainController.php
<?php
namespace test\views\classes;
class MainController
{
public function echoData()
{
echo 'ECHOD';
}
}
test\views\index.php
<?php
require_once '..\autoloader\autoloader.php';
use test\views\classes\MainController;
$cont = new MainController();
$cont->echoData();
test\autoloader\autoloader.php
<?php
spl_autoload_register(null, FALSE);
spl_autoload_extensions('.php');
function classLoader($class)
{
$fileName = strtolower($class) . '.php';
$file = 'classes/' . $fileName;
if(!file_exists($file))
{
return FALSE;
}
include $file;
}
spl_autoload_register('classLoader');
Throws an error:
Fatal error: Class 'test\views\classes\MainController' not found in ..\test\views\index.php on line 6
Am Im missing something!
EDIT: The code works fine when both the index.php and maincontroller.php are in the same directory without using autoloader but using require_once('maincontroller.php');
Does not work if they are in different directories and with autoloader function. Can anyone sort this out.
Thanks
Multiple problems in your code:
The namespace separator (\) is not a valid path separator in Linux/Unix. Your autoloader should do something like this:
$classPath = str_replace('\\', '/', strtolower($class)) . '.php';
if (!#include_once($classPath)) {
throw new Exception('Unable to find class ' .$class);
}
Plus, the paths are all relative. You should set your include path. If your site structure is like this:
bootstrap.php
lib/
test/
views/
index.php
classes/
maincontroller.php
autoloader/
autoloader.php
Your bootstrap.php should look similar to:
$root = dirname(__FILE__);
$paths = array(
".",
$root."/lib",
get_include_path()
);
set_include_path(implode(PATH_SEPARATOR, $paths));
include 'lib/test/autoloader/autoloader.php';
Now, in your test/views/index.php you can just include the bootstrap:
include '../../bootstrap.php';
Add a die statement to your class loader:
$file = 'classes/' . $fileName;
die('File ' . $file . "\n");
And you get
File classes/test\views\classes\maincontroller.php
Is that really where your main controller class lives?

Categories