I have a general class which i like to have it extended by other classes.
I have my directory set up with folders and class files inside of those folders for example
Classes/users/users.class.php
classes/general/general.class.php
I have the users class extending the general class but since they are in different folders I guess the general class is not found.
class users extends general {
}
Can someone please help me out figuring this out.
I should also mention i am using autload function
When you have no autoloader then include the class before.
Then the class is known and you can use it.
require_once(__DIR__.'/../general/general.class.php');
You need to make sure you load both classes or any other class that are required. For example:
In your bootstrap...:
// Set up the include path so that we can easily access the class files
set_include_path('/absolute/path/to/classes'. PATH_SEPARATOR . get_include_path());
require_once('users/users.class.php');
In users.class.php:
require_once('general/general.class.php');
class User {
// you class definition
}
As far as getting the absolute path to your classes folder, youll want to configure this based on your bootstrap location. For example:
// bootstrap lives in $_SERVER['DOCUMENT_ROOT'] and classes is one level up outside the doc root
// this code is in the bootstrap...
$path = realpath(dirname(__FILE__).'/../classes');
set_include_path($path . PATH_SEPARATOR . get_include_path());
Related
spl_autoload_register('Think\Think::autoload');
Under namespace Think\ I created the above register function,when I try to use a class that has not been included like class Storeage,php will surposely pass Storeage as the variable to function Think\Think::autoload,but it actually passed Think\Storeage as the variable,why it adds the extra Think\ to the autoload instead of just Storeage?
Does that mean autoload will only search for classes which are declared under the same namespace where the autoload function is created?
Autoload functions generally work by including files for you on demand. So, for instance, I have a class called Spell in the namespace Write and it's in write/spell.php. So I tell my autoload function how to find the file (in this case, my directories mirror my namespacing).
The autoload function itself doesn't care about namespaces per se. It cares about finding the files that contain your class and loading them. So, to answer your question, your autoload will only restrict itself to a namespace if you write the function to do that.
Now, here's the caveat with the way you're doing it. Your autoload function is already in a namespace. That means you will have to manually include the file that contains that class or else your autoload will fail.
Here is an example for you .
loader.php
namespace bigpaulie\loader;
class Loader {
/**
* DIRECTORY_SEPARATOR constatnt is predefined in PHP
* and it's different for each OS
* Windows : \
* Linux : /
*/
public static function load($namespace){
$filename = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . ".php";
if(file_exists($filename)){
require_once $filename;
}else{
throw new \Exception("Error Processing Request", 1);
}
}
}
index.php
require_once 'path/to/loader.php';
spl_autoload_register(__NAMESPACE__ . 'bigpaulie\loader\Loader::load');
$class1 = new \demos\Class1();
// or
use bigpaulie\core\Class2;
$class2 = new Class2();
as you can see we can use whatever namespace needed we just have to make sure that the path to the class file exists .
Hope this helps!
Best regards,
Paul.
I have a autoload function that looks like so:
function __autoload_HTTP_Client($class_name) {
$HC = $class_name . '.class.php';
return require_once($HC);
}
when i call a class i use the $users = new users();
What i want to do is place my class files in folders within my class directory. So i will have
/users/users.class.php
/general/general.class.php
In my users class i want to be able to extend general.class.php
class users extends general {
}
because I want to be able to use $this-> from general so i dont want to use include. but when i do extend general it says that the class is not found since its in a different directory.
Any ideas on fixing this (I know the autoload needs to change to use directory/ $file.class.php
but how can i extend a class that is outside of the directory of the current class.
Use:
set_include_path(get_include_path().':/users:/general');
The above will then look for files within those directories, and you don't have to use a path, just filename, etc on the include/require inside the autoloader.
I am using a custom scheme in naming my files. Any pointers on how to autoload them with Zend's autoloader?
Thanks!
You can write your own autoloader class and register it with the ZF autoloader. There is a brief bit about this in the manual: http://framework.zend.com/manual/en/zend.loader.autoloader.html#zend.loader.autoloader.interface
Basically it's just a class defining one method which takes the class name as the parameter. So for you it would be something like:
class My_Autoloader implements Zend_Loader_Autoloader_Interface
{
public function autoload($class)
{
$filename = $class.'.obj.php';
require $filename;
}
}
the above assumes the classes are on the include path, if not, just stick the full path in front of $filename. Add any other mapping/checking you need in here and then register it as per the example in the manual. Normally you would do this in your bootstrap.
I'm trying to implement custom exception classes for a zend project.
I use modules and all my classes are under library.
so a filename DuplicateFileException.php which is under
APPLICATION_PATH "/../library/Abra/Exception" contains
class Abra_Exception_FileNotFoundExcpetion extends Exception {}
class Abra_Exception_MissingFileException extends Exception {}
class Abra_Exception_DuplicateFileException extends Exception {}
class Abra_Exception_FileIOException extends Exception {}
so the ErrorController works fine when i only throw Abra_Exception_DuplicateFileException
because there is indeed a file called DuplicateFileException, but the app breaks when i throw any other than that Exception.
I just can't believe that i have to create a file for each of them.
so how to work around it?
thanks for reading.
Proper zend-way would be implementing your own autoloader class. IT will implement autoload method. You can then use Zend_Autoloader autoloader stack to oad your classes. You just need to have some kind of system/logic in your classname->filename mapping.
class Abra_Autoloader
{
public function autoload($className)
{
if (strpos('Abra_Exception', $className) !== false) {
include $someFile; //faster
}
}
}
//anywhere in bootstrap (preferably in some autoloading section of yours)
// autoloader will load only classes starting with "abra"
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
$autoloader->pushAutoloader(array('Abra_Autoloader ', 'autoload'), 'Abra');
Please note that at least teh autoloader class should be Zend_Loader-loadable :)
The Zend autoloader works by mapping requested class names to filesystem paths so you can't make it load a file for a class where the filename does not match.
If you really want to persist down this path, I'd just include the file in your Bootstrap class, eg
protected function _initRequires()
{
require_once 'Abra/Exception/DuplicateFileException.php';
// assuming your "library" folder is on the include path
}
I have a folder in my library folder which is named after my website. The folder path is like:
~\www\library\myWebsite.com
If I'm using Zend autoloader to load the namespace of everything in the library path, will I have any trouble autoloading a class from that file with a namespace like this:
\myWebsite.com\myClass::myFunction();
I have looked online for documentation on this and I can't find any info about using periods in this way.
I tried it and the complication is in PHP. I think Zend is registering the namespace fine, because when I call \Zend_Load_Autoloader::getRegisteredNamespaces() it shows that it's registered. but when I call the static method from the fully qualified namespace, php gives an error of this:
Fatal error: Undefined constant 'myWebsite' in /home/jesse/www/application/controllers/MyController.php on line 15
It seems like PHP is terminating the namespace identifier, during parsing, at the . (period character). This is dissapointing because to me having a library named after the website was important to my design.
I will rename the directory to myWebsitecom or possibly make the .com it's own sub directory like
myWebsite\com and incorporate that into my namespace tree like: \MyNamespace\Com\MyClass::myFunction();
The easiest way to find out is to try it.
If it doesn't work, you could always write a custom autoloader to make it work. I don't have much experience with php namespaces, but the autoloader would look something like this (I imagine you'll have to tinker with it a bit to determine the correct file path given the class name):
<?php
class My_Loader_Autoloader_MyWebsite implements Zend_Loader_Autoloader_Interface {
/**
* (non-PHPdoc)
* #see Zend_Loader_Autoloader_Interface::autoload()
*/
public function autoload($class) {
if (strtolower(substr($class, 0, 9)) == 'mywebsite') {
$file = realpath(APPLICATION_PATH . '/../library/myWebsite.com/' . $class);
if ($file) {
require_once $file;
return $class;
}
}
return false;
}
}
then put this in your bootstrap:
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->pushAutoloader(new My_Loader_Autoloader_MyWebsite());
and if this class must be in that myWebsite.com directory, you could just cheat and throw in a require in there too:
require_once(APPLICATION_PATH . '/../library/myWebsite.com/Loader/Autoloader/MyWebsite.php');