PHP class not found when using class in another class - php

I have 2 class in Two sub folders within a mother folder in am trying to auto load classes within index.php file and then use one into another one but not working yet.Take a look at this->
FOLDER STRUCTURE
MotherFOlder
|- lib
| |- Api.php
|- inc
| | - SC.php
|- index.php
in index.php i am coding like this:
namespace ACX;
use ACX\lib\Api;
use ACX\inc\SC;
spl_autoload_register(__NAMESPACE__ . '\\autoload');
function autoload($class = '') {
if (!strstr($class, 'ACX')) {
return;
}
$result = str_replace('ACX\\', '', $class);
$result = str_replace('\\', '/', $result);
require $result . '.php';
}
Then in Api.php
<?php
namespace ACX\lib;
class Api{
private static $instance = null;
public static function getDataJSON(){
return 'data';
}
public static function getInstance(){
if (empty(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
}
And in SC.php
<?php
namespace ACX\inc;
class SC{
private static $instance = null;
public static function getDataSets(){
$data = Api::getDataJSON();
return $data;
}
public static function getInstance(){
if (empty(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
}
But i am getting this error Fatal error: require(): Failed opening required 'inc/Api.php'
Is there any bug in the code?

It's simple because you forgot to import Api.php class inside SC.php class where you call Api::getDataJSON(). As Api.php is under this ACX\lib namespace, import it as below:
<?php
namespace ACX\inc;
use ACX\lib\Api; // This needs to be imported
class SC {
// other code
public static function getDataSets(){
$data = Api::getDataJSON(); // You're calling Api.php class here
return $data;
}
// other code
}

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

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.

Cannot make non static method - FATAL ERROR

I was working on a PHP web application. I used a new datagrid from gurrido.net and it worked well on the local but when I upload it to the server, I get the following error:
Fatal error: Cannot make non static method Base::getClassName() static
in class Singletons in /var/www/reskb/phpinc/Singletons.class.php on
line 84
In my old version where I didn't use the grid, I got it working. Here is my code of singletons.class.php file:
<?
class Singletons extends Base {
var $objects = array();
function getClassName() {
return 'Singletons';
}
function _instance() {
static $_instance = NULL;
if ($_instance == NULL) {
$className = Singletons::getClassName();
$_instance = new $className();
}
return $_instance;
}
function put($object) {
$self = Singletons::_instance();
$className = $object->getClassName();
$self->objects[$className] = $object;
}
function get($className) {
$self = Singletons::_instance();
if(!empty($self->objects[$className]))
return $self->objects[$className];
else return '';
}
}
Singletons::_instance();
?>
You should call function getClassName using object or define getClassName as static. –
<?php
class Singletons extends Base {
var $objects = array();
static function getClassName() {
return 'Singletons';
}
static function _instance() {
static $_instance = NULL;
if ($_instance == NULL) {
$className = Singletons::getClassName();
$_instance = new $className();
}
return $_instance;
}
function put($object) {
$self = Singletons::_instance();
$className = $object->getClassName();
$self->objects[$className] = $object;
}
function get($className) {
$self = Singletons::_instance();
if(!empty($self->objects[$className]))
return $self->objects[$className];
else return '';
}
}
Singletons::_instance();
?>
You're getting the error because you're trying to call your function statically when it isn't a static method (function).
You need to specify the function as static:
static function getClassName() {
return 'Singletons';
}
That goes for every method you'd like to call statically.
If you declare a function as abstract in an abstract super class, then attempt to define it as static in a child class, you will get a fatal error. You may want to think about the way your class hierarchy is structured, as your only option will be to remove the abstract function declaration from the super class.

Kostache - before() method

Well, is there something like before() method in kostache module? For example, if I have a couple of PHP lines inside of the view file, I'd like to execute them separately inside of the view class, without echoing anything in the template itself. How can I handle that?
You can put this type of code in the constructor of your View class. When the view is instantiated, the code will run.
Here is a (slightly modified) example from a working application. This example illustrates a ViewModel that lets you change which mustache file is being used as the site's main layout. In the constructor, it chooses a default layout, which you can override if needed.
Controller:
class Controller_Pages extends Controller
{
public function action_show()
{
$current_page = Model_Page::factory($this->request->param('name'));
if ($current_page == NULL) {
throw new HTTP_Exception_404('Page not found: :page',
array(':page' => $this->request->param('name')));
}
$view = new View_Page;
$view->page_content = $current_page->Content;
$view->title = $current_page->Title;
if (isset($current_page->Layout) && $current_page->Layout !== 'default') {
$view->setLayout($current_page->Layout);
}
$this->response->body($view->render());
}
}
ViewModel:
class View_Page
{
public $title;
public $page_content;
public static $default_layout = 'mytemplate';
private $_layout;
public function __construct()
{
$this->_layout = self::$default_layout;
}
public function setLayout($layout)
{
$this->_layout = $layout;
}
public function render($template = null)
{
if ($this->_layout != null)
{
$renderer = Kostache_Layout::factory($this->_layout);
$this->template_init();
}
else
{
$renderer = Kostache::factory();
}
return $renderer->render($this, $template);
}
}

How to run method inside a Model | MVC

In the index file i have _autoload and load the libs and then i explode the url to get the wanted contoller and the model if exists. In the view i can see the model __construct() so the model is loaded but if i try to use $this->model->test(); i get
Call to a member function test() on a non-object
http://site.com/about
$this->request = about;
$controller = new $this->request;
$controller->loadModel($this->request);
Everething work ok
*Here is the Main controller *
class Conroller {
function __construct() {
// echo 'Main controller<br />';
$this->view = new View();
}
public function loadModel($name) {
$path = 'models/'.$name.'_model.php';
if (file_exists($path)) {
require 'models/'.$name.'_model.php';
$modelName = $name . '_model';
// **here i make the object**
$this->model = new $modelName();
}
}
}
Here is the About model
class about_model{
function __construct() {
echo 'test';
}
public function test() {
$test = 'test one';
}
}
Here is the About Conroller
class About extends Conroller {
function __construct(){
parent::__construct();
$this->model->test();
$this->view->render('/about');
}
}
You will need to call loadModel in your About controller before you refer to the model:
class About extends Conroller {
function __construct(){
parent::__construct();
$this->loadModel('about');
$this->about->test();
}
}

Categories