Why I am getting "Cannot redeclare class" error? - php

I have Apache running on port 81. My project folder is MyPhpProject. Inside it I have 2 folders: Domain and Testing.
In Domain folder I have 3 PHP files:
BaseDomain.php which contains an abstract class BaseDomain
Location.php which contains a concrete class Location inherited from BaseDomain
Employee.php which contains a concrete class Employee inherited from BaseDomain
Employee class has a reference of Location class.
This is the BaseDomain.php:
<?php
abstract class BaseDomain {
}
?>
This is the Location.php:
<?php
$returnRequire = require 'BaseDomain.php';
class Location extends BaseDomain {
private $locationIdInt;
private $codeNameString;
private $descString;
public function setLocationId($locationId) {
$this->locationIdInt = $locationId;
}
public function getLocationId() {
return $this->locationIdInt;
}
public function setCodeName($codeName) {
$this->codeNameString = $codeName;
}
public function getCodeName() {
return $this->codeNameString;
}
public function setDesc($desc) {
$this->descString = $desc;
}
public function getDesc() {
return $this->descString;
}
}
?>
This is Employee.php:
<?php
$returnRequire = require 'BaseDomain.php';
class Employee extends BaseDomain {
private $employeeIdString;
private $locationObject;
public function setEmployeeId($employeeId) {
$this->employeeIdString = $employeeId;
}
public function getEmployeeId() {
return $this->employeeIdString;
}
public function setLocation($location) {
$this->locationObject = $location;
}
public function getLocation() {
return $this->locationObject;
}
}
?>
Now in the Testing folder I created a Test_Employee.php and this is its code:
<?php
set_include_path('../Domain');
$getIncludePath = get_include_path();
echo "getIncludePath = " . $getIncludePath;
echo "<br>";
$returnRequire1 = require 'Location.php';
echo "returnRequire for Location.php = " . $returnRequire1;
echo "<br>";
$returnRequire2 = require 'Employee.php';
echo "returnRequire for Employee.php = " . $returnRequire2;
echo "<br>";
?>
When I try to run it http://localhost:81/MyPhpProject/Testing/Test_Employee.php I got a fatal error regarding cannot redeclare BaseDomain class. This is what I see in browser:
getIncludePath = ../Domain
returnRequire for Location.php = 1
Fatal error: Cannot redeclare class BaseDomain in C:\Program Files
(x86)\Apache Software
Foundation\Apache2.2\htdocs\MyPhpProject\Domain\BaseDomain.php on line
2
I have not created BaseDomain class more than once. So this error is bizarre. Can somebody please explain why I am getting error message? And how to fix it.
Thanks for your time.

The line $returnRequire1 = require 'Location.php'; loads Location.php, which in turns loads BaseDomain.php in the line $returnRequire = require 'BaseDomain.php';. Then, the line $returnRequire2 = require 'Employee.php'; loads Employee.php, which loads (again) BaseDomain.php (the line $returnRequire = require 'BaseDomain.php';). The second load of BaseDomain.php causes php to try to redefine the BaseDomain class, which is no allowed.
The easiest way to solve this problem is to change your require calls to require_once. This will ensure that each file is loaded exactly once per run, which will prevent the error you are experiencing.

BaseDomain.php:
<?php
abstract class BaseDomain {
}
?>
Location.php
<?php
class Location extends BaseDomain {
private $locationIdInt;
private $codeNameString;
private $descString;
public function setLocationId($locationId) {
$this->locationIdInt = $locationId;
}
public function getLocationId() {
return $this->locationIdInt;
}
public function setCodeName($codeName) {
$this->codeNameString = $codeName;
}
public function getCodeName() {
return $this->codeNameString;
}
public function setDesc($desc) {
$this->descString = $desc;
}
public function getDesc() {
return $this->descString;
}
}
?>
Employee.php:
<?php
class Employee extends BaseDomain {
private $employeeIdString;
private $locationObject;
public function setEmployeeId($employeeId) {
$this->employeeIdString = $employeeId;
}
public function getEmployeeId() {
return $this->employeeIdString;
}
public function setLocation($location) {
$this->locationObject = $location;
}
public function getLocation() {
return $this->locationObject;
}
}
?>
Test_Employee.php
<?php
set_include_path(__DIR__.'/MyPhpProject/Domain');
require 'BaseDomain.php';
$getIncludePath = get_include_path();
echo "getIncludePath = " . $getIncludePath;
echo "<br>";
$returnRequire1 = require 'Location.php';
echo "returnRequire for Location.php = " . $returnRequire1;
echo "<br>";
$returnRequire2 = require 'Employee.php';
echo "returnRequire for Employee.php = " . $returnRequire2;
echo "<br>";
?>

Related

How to use namespace properly in PHP?

I have this file root/core/Router.php
<?php
namespace Core;
class Router {
protected $url;
protected $controller;
private function parseURL() {
// threat the $this->url; for example ["r", "product"]
}
private function request() {
$this->controller = Controller::get($this->url[1]);
}
public function __construct() {
$this->parseURL();
$this->request();
}
}
?>
then file root/core/Controller.php
<?php
namespace Core;
class Controller {
public static function model($name, $params = []) {
$model = "\\Model\\$name";
return new $model($params);
}
public static function view($name, $params = []) {
require_once APP_DIR . "view/" . $name . ".php";
}
public static function get($name, $params = []) {
require_once APP_DIR . "controller/" . $name . ".php";
$name = "\\Controller\\$name";
return new $name($params);
}
}
?>
then root/controler/Product.php
<?php
namespace Controller;
use Core\Controller;
use Model\Product;
class Product {
public function get() {
$ret['state'] = 510;
$productModel = new Product;
$products = $productModel->getAll();
if(isset($products)) {
$ret['products'] = $products;
$ret['state'] = 200;
}
return $ret;
}
}
?>
then file root/model/Product.php
<?php
namespace Model;
class Product {
public function add($values) {
return Database::insert("product", $values);
}
}
?>
and root/core/Model.php
<?php
namespace Core;
class Model {
protected $table = null;
public function getAll() {
// some code to collect data
}
}
?>
What i want to achive is that every Controller in root/controller/*.php able to load any Model in root/model/*.php but class inside root/model/*.php must able to access (inheritance/extends) the Model class inside root/core/Model.php i firstly asked on chatGPT for some AI Generated answer, that the reason why i get this far.
Then i get this error, when the AI keep giving the same answer.
Fatal error: Cannot declare class Controller\Product because the name is already in use in C:\xampp\htdocs\app\shop\controller\Product.php on line 6
I actually realize that the simple way probably with naming the class so ther no conflict between it but i became aware how to properly using the namespace if its such features in php. Those files loaded without any autoloader, so i just require_once each file in root/init.php file.
I read few documentations but hard to implement in multiple files and directorys.
I Apreciate any feedback, thanks

Require has failed in php

I'm new to PHP, I'm trying to require UserController.php from Controller.php but all I get is "HTTP ERROR 500" in browser. What's going on here?
Controller.php
class Controller
{
public function __construct()
{
}
public function call(){
// echo 1;
require_once "../Controllers/UserController.php";
}
}
UserController.php
class UserController
{
public function __construct()
{
echo '111111111';
}
public function hi(){
echo '1';
}
}
$a = new UserController();
$a->hi();
Class definitions can't be nested inside functions or other classes. So you shouldn't have that require_once line inside a function definition. Move it outside the class.
require_once "../Controllers/UserController.php";
class Controller
{
public function __construct()
{
}
public function call(){
// echo 1;
}
}
<?php
require_once "../Controllers/UserController.php";
class Controller
{
public function __construct()
{
}
public function call(){
// echo 1;
$a = new UserController();
$a->hi();
}
}

Class not found in PHP - Scope Resolution

I got 2 PHP files:
courier.php
<?php
namespace Shipping;
class Courier
{
public $name;
public $home_country;
public function __construct($name) {
$this->name = $name;
return true;
}
public function ship($parcel) {
// sends the parcel to its destination
return true;
}
public static function getCouriersByCountry($country) {
// get a list of couriers with their home_country = $country
// create a Courier object for each result
// return an array of the results
return $courier_list;
}
}
?>
filephp.php
<?php
//namespace Fred;
require 'courier.php';
//function __autoload($classname) {
// include //strtolower($classname).'.php';
//}
$mono = new Shipping\Courier('Monospace Delivery');
//var_dump($mono);
// accessing a property
echo "Courier Name: " . $mono->name;
// calling a method
$mono->ship($parcel);
$spanish_couriers = Courier::getCouriersByCountry('Spain');
echo $spanish_couriers;
?>
But when I execute filephp.php I get this error:
Fatal error: Class 'Courier' not found in D:\masterphp\test.php on line 19
line 19 is this:
$spanish_couriers = Courier::getCouriersByCountry('Spain');
What is wrong with my scope resolution?
You are missing the Shipping namespace, it should be \Shipping\Courier::...

Class autoload not working

I'm a beginner in PHP development and I'm facing a problem in my development in PHP OO. I saw is better use the autoload() function than include each file of PHP Class.
My doubt is: Why my autoload function does not work?
Follow bellow my code:
<?php
function __autoload($class)
{
include_once "model/{$class}.class.php";
}
$avaliacaoLocal = new AvaliacaoLocal();
$avaliacaoLocal->setId(1);
$avaliacaoLocal->setIdLocal(2);
$avaliacaoLocal->setComentarios("Comentários de Pedro");
$avaliacaoLocal->setIdPessoaCliente(3);
$avaliacaoLocal->setValor(5);
var_dump($avaliacaoLocal);
File AvaliacaoLocal.class.php
<?php
namespace model;
class AvaliacaoLocal
{
private $id;
private $valor;
private $comentarios;
private $idLocal;
private $idPessoaCliente;
public function __construct(){
$this->clear();
}
public function clear(){
$this->id = 0;
$this->valor = 0;
$this->comentarios = "";
$this->idLocal = null;
$this->idPessoaCliente = null;
}
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function getValor()
{
return $this->valor;
}
public function setValor($valor)
{
$this->valor = $valor;
}
public function getComentarios()
{
return $this->comentarios;
}
public function setComentarios($comentarios)
{
$this->comentarios = $comentarios;
}
public function getIdLocal()
{
return $this->idLocal;
}
public function setIdLocal($idLocal)
{
$this->idLocal = $idLocal;
}
public function getIdPessoaCliente()
{
return $this->idPessoaCliente;
}
public function setIdPessoaCliente($idPessoaCliente)
{
$this->idPessoaCliente = $idPessoaCliente;
}
}
The error:
PHP Fatal error: Class 'AvaliacaoLocal' not found in C:\Users\Pedro
........\index.php on line 14
UPDATE:
When i use include the PHP returns the same error:
Fatal error: Class 'AvaliacaoLocal' not found in C:\Program
Files\VertrigoServ\www\system\index.php on line 10
i've change folder to verify if could be it.
The class is declared belonging to a namespace, you have to call it in this way:
$avaliacaoLocal = new \model\AvaliacaoLocal();
But now, the namespace is also included in $class, so the autoload function needs to handle that:
function __autoload($class)
{
$file = str_replace(array('_', '\\'), '/', $class) . '.php';
if (is_file($file)) {
require $file;
}
}
This function takes $class value and replace every \ (and _) from the namespace with a / to get the file name.

using php include function for classes

Trying to get a hang of classes in php, trying to include carClass.php into new_file.php.
carClass.php
<?php
class carClass
{
private $color;
private $gear;
private $model;
private $gas;
function paintCar($carColor) {
$this->color = $carColor;
}
function findCarColor() {
echo "$color";
}
function shiftGear($newGear) {
$this->gear=$newGear;
}
function findGear() {
echo "$gear";
}
function chooseModel($newModel) {
$this->model = $newModel;
}
function findModel() {
echo"$model";
}
function fillCar($gasAmount) {
$this->gas = $gasAmount;
}
function lookAtGauge() {
echo "$gas";
}
}
?>
its just a bunch of getters and setters. Im trying to include this class to new_file.php
new_file.php
<?php
include("carClass.php");
$car = new carClass;
$car->chooseModel("Mustang");
$car->paintCar("black");
$car->shiftGear("5th");
$car->fillCar("half");
$car->findModel();
$car->findCarColor();
$car->findGear();
$car->lookAtGuage();
?>
When I try to execute this file I get these error messages
Warning: include(carClass.php): failed to open stream: No such file or directory in C:\xampp\htdocs\testFile\new_file.php on line 4
Warning: include(): Failed opening 'carClass.php' for inclusion (include_path='.;C:\xampp\php\PEAR') in C:\xampp\htdocs\testFile\new_file.php on line 4
Fatal error: Class 'carClass' not found in C:\xampp\htdocs\testFile\new_file.php on line 6
I believe both files are in testFile directory so I'm not sure whats going on. I appreciate any help you guys can give me as usual.
The include path is set against the server configuration (PHP.ini) but the include path you specify is relative to that path so in your case the include path is (actual path in windows):
<?php
include_once dirname(__FILE__) . '/carClass.php';
$car = new carClass;
$car->chooseModel("Mustang");
$car->paintCar("black");
$car->shiftGear("5th");
$car->fillCar("half");
$car->findModel();
$car->findCarColor();
$car->findGear();
$car->lookAtGuage();
?>
You can use PHP's auto loading feature which will automatically load a class when an object is created. If you have many classes then you can use it an header file so that you don't need to worry about using this include every time.
<?php
function __autoload($class_name) {
include $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
Try this:
<?php
class carClass
{
private $color;
private $gear;
private $model;
private $gas;
function paintCar($carColor) {
$this->color = $carColor;
}
function findCarColor() {
echo $this->color;
}
function shiftGear($newGear) {
$this->gear=$newGear;
}
function findGear() {
echo $this->gear;
}
function chooseModel($newModel) {
$this->model = $newModel;
}
function findModel() {
echo $this->model;
}
function fillCar($gasAmount) {
$this->gas = $gasAmount;
}
function lookAtGauge() {
echo $this->gas;
}
}
?>
//
<?php
include("carClass.php");
$car = new carClass;
$car->chooseModel("Mustang");
$car->paintCar("black");
$car->shiftGear("5th");
$car->fillCar("half");
$car->findModel();
$car->findCarColor();
$car->findGear();
$car->lookAtGauge();
?>

Categories