Some things to keep in mind when requiring files:
- You must have the correct path.
- The file must have read permissions.
- Dependencies must be loaded first. If the class extends an abstract, has interfaces or traits, those must be loaded before the class declaration is reached. Likewise if dependencies also have dependencies, those must also be loaded before the dependencies themselves are loaded.
As per your listed information, #3 seems to be your problem. The parent class must be loaded before the child class declaration.
good practice to make this easier:
- Declare constants that map to your application root, libraries, etc. before you need to require various files, so you will not need to use complicated navigation to find them.
- Use an autoloader, preferably psr-0 or psr-4 compliant.
The quick way to check (reasonably robustly):
/**
* Provided for documentor/apigen support.
* This function will attempt to load a file, and return information about
* failure if it cannot be found or is not readable. It will also by default
* avoid double inclusion to prevent redeclaration errors, though this can be
* configured to be ignored if required.
* NOTE: This function will mitigate common inclusion mistakes like duplicated or missing directory separators and file extensions.
* @param string $file The name of the file, may be the actual file or full path.
* @param string $dir (optional) The directory to check for the file. This param is best used with search functions that know the file name but not explicitly the directory, which allows for more robust usage elsewhere with minimal variable modification. This function can be used perfectly fine without it though.
* @param string $suffix (optional) The file suffix that will be checked for. This will be appended to your file, and defaults to .php. You must alter this parameter if you are searching for a different file type.
* @param boolean $nodup (optional) If true, will not include a file that has already been loaded to prevent class redeclaration errors. If false, will require the file regardless.
* @return boolean TRUE if file was included, FALSE if not included (NOTE: you may want to modify the return line in the catch block depending on your needs.)
*/
function _requireFile($file, $dir = NULL, $suffix = '.php', $nodup = TRUE) {
//this is not necessary in this example, but is generally good practice, and will prevent accidentally duplicated or missing extensions.
//This function assumes that it will be used frequently, and contains redundancies to mitigate common inclusion errors such as missing or duplicated extenstions, missing or duplicated directory separators, etc.
$file = ( ( isset($dir) ) ? rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : NULL ) . rtrim($file, $suffix) . $suffix);
try {
if (!file_exists($file)) {
//the file does not exist at the specified location, throw an exception with information about the request.
throw new \Exception("File not found at: " . $file);
} elseif (file_exists($file) && !is_readable) {
//the file exists in the specified location, but cannot be read due to a file permission conflict. Throw an exception with information about the request and how to fix it.
throw new \Exception("File exists but is not readable at: " . $file . " <hr>You can correct this by using 'chmod 755 " . $file . "' from the command line.");
}
//This allows you to perform a duplication check to avoid class redeclaration errors. If you intend to include the file multiple times, pass the $nodup param as FALSE or 0 to ignore this check.
if (!$nodup == TRUE && in_array($file, get_included_files())) {
return FALSE;
} else {
//The file exists, is readable, and passed the no-duplication check, require the file. Note that require_once was intentionally not used to provide the option to require files multiple times if needed. If you are only ever going to use this for files that should not be redeclared, you can change this to require_once but it will really not make any appreciable difference.
require($file);
return TRUE;
}
} catch (\Exception $e) {
//You may want to use a logging function here rather than echoing to the screen. The echo statement is provided for quick debugging, but should not be used in production.
echo 'Error fetching file at ' . $e->getLine() . ' of ' . $e->getFile() . ': ' . $e->getMessage();
//you may want to rethrow the exception and catch it in the referencing method or function, kill the program, or otherwise mitigate errors here depending on your program structure. Non-essential files should not kill your program though.
return FALSE;
}
}
$file = "/path/to/file.php";
_requireFile($file);
//OR
$dir = "/path/to/";
$file = "/path/to/file.php";
_requireFile($file, $dir);
//OR
$dir = "/path/to/";
$file = "/path/to/file";
$suffix = ".php";
_requireFile($file, $dir, $suffix);
The better way:
-Use a PSR-4 or PSR-0 autoloader.
Ticketclass?