Jump to content
  • 0

Наследование


alexandr.coder
 Share

Question

Есть классы: Core, Controller, Loader и site.

Класс Core наследует Controller, класс Controller наследует site. Объект класса Loader создается в классе Core.

$this -> load = new Loader();

Но при попытки вызова метода класса Loader в классе site:

$this -> load -> view("header");

,выдается такая ошибка:

Notice: Undefined property: site::$load in S:\home\dev\www\system\application\controllers\site.php on line 12
Call to a member function view() on a non-object in S:\home\dev\www\system\application\controllers\site.php on line 12

По идее объект $this -> load должен быть доступен в классе site, но происходит какая-то ошибка.Помогите.

Link to comment
Share on other sites

Recommended Posts

  • 0

Я выяснил, что проблема начинается ещё на уровне класса Controller

<?php 

class Controller extends Core{

protected $url_data = array();

public function __construct($data = array())
{
$this -> url_data = $data;
}

function view($view)
{
$this -> load -> view($view);
}

}

?>

Notice: Undefined property: site::$load in S:\home\dev\www\system\classes\controller.php on line 14
Fatal error: Call to a member function view() on a non-object in S:\home\dev\www\system\classes\controller.php on line 14

Почему-то Controller не наследует класс Core

Edited by alexandr.coder
Link to comment
Share on other sites

  • 0
покажите где в классе Core создается объект класса Loader.

class Core{

protected $load;
protected $registry;

function run()
{

$this -> load = new Loader();
$this -> registry = new Registry();
$this -> registry -> load_config();

$url_fragments = explode("/", $_SERVER['REQUEST_URI']);

if($url_fragments[1] != "") $controller = $url_fragments[1];
else $controller = $this -> registry -> get_config_item("default","controller");

if(isset($url_fragments[2])) $action = $url_fragments[2];
else $action = $this -> registry -> get_config_item("default","action");

if(isset($url_fragments[3])) $data = array_slice($url_fragments,3);
else $data = array("");

if(!file_exists(SYSTEM."/application/controllers/".$controller.".php")) die();
require_once(SYSTEM."/application/controllers/".$controller.".php");
$controller = new $controller($data);
$controller -> $action();

}

}

Link to comment
Share on other sites

  • 0
Ошибка возникает потому что в классе Сore, создается объект класс Loader после того, как его наследует Controller.

А это когда иммено? Когда подключается файл с контроллером?

p.s. а что это такое вообще? не фреймворк случайно?

Да. Что-то типа этого.

Link to comment
Share on other sites

  • 0
Когда создаются объекты классов Core и Controller.

Структура такая:

index.php - точка входа
system
classes
core.php
registry.php
loader.php
controllers
models
views
...

Объект класса Core создается в самом начале исполнения приложения - в index.php.

<?php 

error_reporting(E_ALL);

if ( !version_compare ( PHP_VERSION , '5.0.0' , '>=' )) die();

define("SYSTEM","system");

require_once(SYSTEM."/classes/core.php");
$core = new Core();
$core -> run();

?>

Он подключает ядро, создает новый объект-ядро и запускает приложение.

С самого начала объекта класса Controller небыло вообще. В нем не было необходимости. Он служил как шаблон, который должен расширяться контроллерами. Но подумав, что объект этого класса надо создать я сделал это в самом конце метода-загрузчика.

		$this -> load = new Loader();
$this -> registry = new Registry();
$this -> registry -> load_config();

if(stristr($_SERVER['REQUEST_URI'],"select")) die();
if(stristr($_SERVER['REQUEST_URI'],"union")) die();
if(stristr($_SERVER['REQUEST_URI'],"order")) die();
if(stristr($_SERVER['REQUEST_URI'],"char")) die();
if(stristr($_SERVER['REQUEST_URI'],"where")) die();
if(stristr($_SERVER['REQUEST_URI'],"from")) die();
if(stristr($_SERVER['REQUEST_URI'],"drop")) die();

$url_fragments = explode("/", $_SERVER['REQUEST_URI']);

if($url_fragments[1] != "") $controller = $url_fragments[1];
else $controller = $this -> registry -> get_config_item("default","controller");

if(isset($url_fragments[2])) $action = $url_fragments[2];
else $action = $this -> registry -> get_config_item("default","action");

if(isset($url_fragments[3])) $data = array_slice($url_fragments,3);
else $data = array("");


// глухо // $front_controller = new Controller():
if(!file_exists(SYSTEM."/application/controllers/".$controller.".php")) die();
require_once(SYSTEM."/application/controllers/".$controller.".php");
$controller = new $controller($data);
$controller -> $action();

Т.е. после содания объектов $this -> load и $this -> registry.

Link to comment
Share on other sites

  • 0
Надо поместить создание объектов в __construct() и будет всё работать.

Так?

<?php 

require_once(SYSTEM."/classes/controller.php");
require_once(SYSTEM."/classes/model.php");

class Framework_Core{

protected $load;
protected $registry;
protected $error;

public function __construct(){

//Подключение обработчика ошибок
require_once (SYSTEM."/classes/error.php");

//Инсцилизация системы безопасности
require_once (SYSTEM."/classes/security.php");
$this -> security = new Framework_Security();

//Инсцилизация реестра
require_once (SYSTEM."/classes/registry.php");
$this -> registry = new Framework_Registry();

//Инсцилизация загрузчика
require_once (SYSTEM."/classes/loader.php");
$this -> load = new Framework_Loader();

//Проверка всех данных пользователя перед входом
$this -> security -> enter();

//Мини-роутинг

$route = explode("/", $_SERVER['REQUEST_URI']);

if($route[1] != "") $controller = $route[1];
else $controller = $this -> registry -> get_config("route", "controller");

if(isset($route[2])) $action = $route[2];
else $action = $this -> registry -> get_config("route", "action");

if(isset($route[3])) $data = array_slice($route,3);
else $data = array();

echo "application $controller.$action<br>";

if(!file_exists(SYSTEM."/application/controllers/".$controller.".php")) die();
require_once(SYSTEM."/application/controllers/".$controller.".php");
$controller = "Framework_Controller_".$controller;
$front_controller = new $controller($data);
$front_controller -> $action();
}


}

?>

Есть ещё такой вопрос: можно ли расширять Framework_Core классами Framework_Security, Framework_Registry, Framework_Loader если в классе Framework_Core создаются объекты этих классов?

		//Инсцилизация системы безопасности
require_once (SYSTEM."/classes/security.php");
$this -> security = new Framework_Security();

//Инсцилизация реестра
require_once (SYSTEM."/classes/registry.php");
$this -> registry = new Framework_Registry();

//Инсцилизация загрузчика
require_once (SYSTEM."/classes/loader.php");
$this -> load = new Framework_Loader();

Edited by alexandr.coder
Link to comment
Share on other sites

  • 0
Так?

Ну то что в функции run засунуть в __construct()

Есть ещё такой вопрос: можно ли расширять Framework_Core классами Framework_Security, Framework_Registry, Framework_Loader если в классе Framework_Core создаются объекты этих классов?

И как вы это себе представляете?

Link to comment
Share on other sites

  • 0

<?php 

error_reporting(E_ALL);
if ( !version_compare ( PHP_VERSION , '5.2.0' , '>=' )) die();
define("SYSTEM","system");
require_once(SYSTEM."/classes/core.php");
$core = new Framework_Core();

?>

<?php 

require_once(SYSTEM."/classes/controller.php");
require_once(SYSTEM."/classes/model.php");

class Framework_Core{

protected $load;
protected $registry;
protected $error;
protected $security;

public function __construct(){

//одключение обработчика ошибок
require_once (SYSTEM."/classes/error.php");

//Инсцилизация системы безопасности
require_once (SYSTEM."/classes/security.php");
$this -> security = new Framework_Security();

//Инсцилизация реестра
require_once (SYSTEM."/classes/registry.php");
$this -> registry = new Framework_Registry();

//Инсцилизация загрузчика
require_once (SYSTEM."/classes/loader.php");
$this -> load = new Framework_Loader();

//Проверка всех данных пользователя перед входом
$this -> security -> enter();

//Мини-роутинг

$route = explode("/", $_SERVER['REQUEST_URI']);

if($route[1] != "") $controller = $route[1];
else $controller = $this -> registry -> get_config("route", "controller");

if(isset($route[2])) $action = $route[2];
else $action = $this -> registry -> get_config("route", "action");

if(isset($route[3])) $data = array_slice($route,3);
else $data = array();

echo "application $controller.$action<br>";


if(!file_exists(SYSTEM."/application/controllers/".$controller.".php")) die();
require_once(SYSTEM."/application/controllers/".$controller.".php");
$controller = "Framework_Controller_".$controller;
$Framework_Controller = new Framework_Controller();
$front_controller = new $controller($data);
$front_controller -> $action();
}


}

?>

<?php 

class Framework_Controller extends Framework_Core{

protected $data = array();

public function __construct($data = array()){
$this -> data = $data;
}

}

?>

<?php 

class Framework_Controller_site extends Framework_Controller {

public function __construct($data)
{
parent::__construct($data);
}

function index()
{
$this -> load -> view();
}

}

?>

Link to comment
Share on other sites

  • 0
в прошлый раз вызов $this->load->view() вызывался в главном контроллере а теперь в подконтроллере. но, в подконтроллере создается опять __construct и опять $this->load удаляется.

А будет ли доступна в подконтроллере переременная определенная в ядре, если конструкторов не будет?

Link to comment
Share on other sites

  • 0
Знакомая проблема, для себя решил ее так. Строка <? $this->load->view('header'); ?> вызывалась в файле views/bla-bla.php, а не в контроллере.

CodeIgniter.

Не очень разумное решение. Ещё никогда не видел чтоб вьювер вызывался в вьювере. Это может увелчить количество Вьюверов до 2 раз, что не есть хорошо. И что вы хотели сказать последней строкой?

Link to comment
Share on other sites

  • 0
Лишь название фреймворка, в котором это у меня применялось.

И чем грозит увеличение вьюверов?

Хм. В CodeIgniter вроде такая же структура которую я пытаюсь реализовать. А увеличение кол-ва вьюверов грозит большой запутанностью.

Link to comment
Share on other sites

  • 0

Появилась какая-то другая проблема:

class Framework_Registry{

protected $config = array();
protected $memory = array();

public function __construct(){
require_once(SYSTEM."/application/config/config.php"); //9строка
$this -> config = $config;
echo "Done";
}

public function get_config($group,$set){
return $this -> config[$group][$set];
}

public function set_memory($group,$set,$str){
$this -> config[$group][$set] = str;
}

public function get_memory($group,$set){
return $this -> config[$group][$set];
}


}

В классе Registry __construct() выполняется два раза

Include

Done

Notice: Undefined variable: config in S:\home\dev\www\system\classes\registry.php on line 10

Done

А если вместо require_once в конструкторе использовать require то по каким-то причинам конструктор будет выполняться ещё раз и ещё раз пока не дойдет до предела памяти.

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 261904 bytes) in S:\home\dev\www\system\application\config\config.php on line 9

В чем проблема?

И ещё вопрос: есть ли инструмент, с помощью которого можно просмотреть в таблице ход выполнения скрипта с затраченным временем.

Link to comment
Share on other sites

  • 0

Проблема решена:

<?php 

require_once(SYSTEM."/classes/controller.php");
require_once(SYSTEM."/classes/model.php");

class Framework_Core{

protected $load;
protected $registry;
protected $error;
protected $security;

public function __construct(){

//одключение обработчика ошибок
require_once (SYSTEM."/classes/error.php");

//Инсцилизация системы безопасности
require_once (SYSTEM."/classes/security.php");
$this -> security = new Framework_Security();

//Инсцилизация реестра
require_once (SYSTEM."/classes/registry.php");
$this -> registry = new Framework_Registry();

//Инсцилизация загрузчика
require_once (SYSTEM."/classes/loader.php");
$this -> load = new Framework_Loader();
}

public function run(){
//Проверка всех данных пользователя перед входом
$this -> security -> enter();

//Мини-роутинг

$route = explode("/", $_SERVER['REQUEST_URI']);

if($route[1] != "") $controller = $route[1];
else $controller = $this -> registry -> get_config("route", "controller");

if(isset($route[2])) $action = $route[2];
else $action = $this -> registry -> get_config("route", "action");

if(isset($route[3])) $data = array_slice($route,3);
else $data = array();

if(!file_exists(SYSTEM."/application/controllers/".$controller.".php")) die();
require_once(SYSTEM."/application/controllers/".$controller.".php");
$controller = "Framework_Controller_".$controller;
$Framework_Controller = new Framework_Controller();
$front_controller = new $controller($data);
echo "<br><br><br>Controller run...";
$front_controller -> $action();
}


}

?>

<?php 

class Framework_Controller extends Framework_Core{
}

?>

Отталась ещё одна проблема. конструктор класса реестра запускается 3 раза.

Edited by alexandr.coder
Link to comment
Share on other sites

  • 0

Так в конструкторе класса Framework_Core сделайте перед каждым подключением класса - проверку

if (!class_exists('Error'))
{
//подключение обработчика ошибок
require_once (SYSTEM."/classes/error.php");
}

if (!class_exists('Framework_Security'))
{
//Инсцилизация системы безопасности
require_once (SYSTEM."/classes/security.php");
$this -> security = new Framework_Security();
}

и так далее.

Link to comment
Share on other sites

  • 0
Так в конструкторе класса Framework_Core сделайте перед каждым подключением класса - проверку

if (!class_exists('Error'))
{
//подключение обработчика ошибок
require_once (SYSTEM."/classes/error.php");
}

if (!class_exists('Framework_Security'))
{
//Инсцилизация системы безопасности
require_once (SYSTEM."/classes/security.php");
$this -> security = new Framework_Security();
}

и так далее.

Если так сделать то этими классами нельзя будет пользоваться в подконтроллерах.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy