I'm trying to include a class in PHP and to use the methods from this class in another file. My code looks like that (small reproducable example). By the way: I'm working on a WordPress environment.
Main file:
include 'class-file.php';
$cars = new Cars();
var_dump($cars->getCars());
File class-file.php:
class Cars {
public function getCars() {
return "No Cars";
}
}
I get the following error:
Fatal error: Uncaught Error: Call to undefined method Cars::load() in /..../wp-content/themes/builder/includes/elements.php
Seems that my class instance is connected with another class from the theme. But why? Can I disconnect the class from any others? If yes, how?
Maybe the theme doesn't use namespaces, which makes all its classes discoverable from the global namespace, and by defining your own Cars class, you override the theme's class.
Try to define your namespace, and check if the conflict is gone.
Main file:
include 'class-file.php';
$cars = new \mycode\Cars();
var_dump($cars->getCars());
File class-file.php:
namespace mycode;
class Cars {
public function getCars() {
return "No Cars";
}
}
Related
I have a folder test. In this folder I have a two classes, TestHeader and TestHeaders.
This is TestHeader class
<?php
class TestHeader
{
public function send(): void
{
}
}
This is TestHeaders class
<?php
class TestHeaders
{
public function profile(int $userId): TestHeader
{
return new TestHeader();
}
}
And when I run tests, show me error Fatal error: Uncaught Error: Class "TestHeader" not found in C:\project\test\TestHeaders.php:7 I don't know why show this error. Someone could me explain why this error is and how I can fix it ?
if you'r not using a php framework that implement the autoload and if you not set up an autoload strategy you have to include all file you'r trying to use in another file.
add include("TestHeader.php"); at start of TestHeaders class, on the line immediately after the <?php tag
I basically have the following directory structure
MiniCrawler
Scripts/
htmlCrawler.php
index.php
This is the index.php
use Scripts\htmlCrawler;
class Main
{
public function init()
{
$htmlCrawler = new htmlCrawler();
$htmlCrawler->sayHello();
}
}
$main = new Main();
$main->init();
And this is the /Scripts/htmlCrawler.php
namespace Scripts;
class htmlCrawler
{
public function sayHello()
{
return 'sfs';
}
}
The code throws the following error
Fatal error: Class 'Scripts\htmlCrawler' not found in
/mnt/htdocs/Spielwiese/MiniCrawler/index.php on line 9
You forgot to include the file /Scripts/htmlCrawler.php in your index.php file.
require_once "Scripts/htmlCrawler.php";
use Scripts\htmlCrawler;
class Main
{
public function init()
{
$htmlCrawler = new htmlCrawler();
$htmlCrawler->sayHello();
}
}
$main = new Main();
$main->init();
Your index file cannot find the definition of the htmlCrawler file if you never provide the file defining this class, and the use of namespaces doesn't automatically include the required classes.
The reason why frameworks don't require you to include manually the file and you can simply add the use statement is because they're handling the inclusion of required classes for the developer. Most of the frameworks are using composer to handle the automatic inclusion of the files.
You can obtain a somewhat similar functionality using autoloading.
Currently I am trying to understand how OOP applies to PHP and I am having trouble with calling my class when I am getting into inheritance.
I am using the following PHP code:
require_once("init.php");
$table = new Table();
$table->draw();
$customer1 = new Customer();
Since the table class is just a plain class (not inherited) it will load correctly.
The init.php has the following PHP code:
function __autoload($class_name) {
require_once('classes/'.$class_name . '.class.php');
}
Because the Customer class is inhereting the User class, the code for the Customer class is inside the User class, however the __autoload function is trying to call for the customer.class.php now.
My Customer class would look something like this:
class User
{
private $_username;
public function __construct($name)
{
$this->_username = $name;
}
public function getUsername()
{
return $this->_username;
}
}
class Customer extends User
{
public function __construct()
{
//some code here
}
}
Cany anyone explain me please how I should call an inherited class with PHP?
You should only have one class per file. Your autoload will handle everything for you as long as every class is in its own file, named the same way...
Put all your Customer class code inside Customer.class.php
Each class should be written in its own file, exactly because of this autoload. There's no reason why class Customer must be within the same file as class User, just put it in its own file and your autoloader will handle it correctly.
Otherwise, you'll have to adopt some other naming scheme and write a more intelligent autoloader which can find classes in files with different names. (Don't do that, not really.)
I'm trying to get working use.
My file is in /application/controllers/indexController.php
use application\models\Database;
class IndexController extends Controller {
public function indexAction() {
$db = new Database();
$this->view->render('index','template');
}
}
My Database class is in /application/models/Database.php so i wrote use application\models\Database
But it tells
Fatal error: Class 'application\models\Database' not found in
Z:\home\localhost\www\application\controllers\IndexController.php on
line 7
How i can get it worked?
use is not magical.
You need an autoloader to tell it where to find a certain namespace.
So right now your code is looking for a class called application\models\Database in the same directory as your currently executing file.
I think what you meant to do is:
include 'application\models\Database.php';
I have an exception in application/core named prefix_Exceptions.php with the same class name. I try to throw this exception from a controller and I get:
Fatal error: Class 'prefix_Exceptions' not found in user_controller.php
In application/core/prefix_Exceptions.php:
<?php
class prefix_Exceptions extends CI_Exceptions {
public function __construct() {
parent::__construct();
}
public function test() {
echo "This is a test.";
}
}
And in application/controllers/user_controller.php:
<?php
class User_Controller extends CI_Controller {
public function view($id = '0') {
$this->load->model('user_model');
$u = $this->user_model->getUser($id);
if (!isset($u)) {
$this->exceptions->test(); // ???
}
echo "Test: $u";
}
}
Oh, and my prefix is set to prefix_:
$config['subclass_prefix'] = 'prefix_';
I've read about a dozen threads on this issue and none of them fix my exception so that it can be thrown by the controller.
The main reason your code is not working, is (as the error message suggests): your prefix_invalid_user.php is never loaded. CI does not know to load this file, as you are not following the required file naming scheme.
If you want to extend a built-in class, you have to use the same class name, except you change the prefix from CI_ to MY_ (or whatever prefix you set in your config).
To extend the class CI_Exceptions you would have to name it MY_Exceptions and save that php file in /application/core/MY_Exceptions.php. Then, and only then, will CI auto-load it for you.
However you should also know that CI's exceptions class isn't actually for throwing exceptions (the name is misleading, but CI_Exceptions handles error reporting). As you can see in the /system/core/Exceptions.php file, the CI_Exceptions class does not extend PHP's native Exceptions class, which is necessary to create custom, throwable exceptions.
If you want custom, throwable exceptions you have to create your own wrapper for them, and load/autoload it as a library.
Edit:
As per the OP's request, I'm adding the other half of the solution, which was to simply fetch the class object from CI's innards. For this, we can use the load_class function, which will return our class object if it has been instantiated, and if not, it will instantiate and return it.
$foo = load_class('Exceptions', 'core', $this->config->item('subclass_prefix'))
Then we can access the methods of our custom Exceptions class as so:
$foo->someMethodName();