I am trying to create a new model object from my mvc controller but the page doesn't generate. Is there any reason why I can't do this? Surely I should be able to create an object inside an existing one?
Sorry to be so simplistic, and I know I sound like an idiot, but I'm not sure how to explain what I am doing wrong.
class controller_landing extends controller_base
{
public function __construct($get,$post)
{
parent::__construct($get,$post);
$this->model = new model_landing; <-----problem line here
}
}
abstract class controller_base
{
//store headers
protected $get;
protected $post;
//store layers
protected $view;
protected $model;
protected function __construct($get,$post)
{
//store the header arrays
$this->get = $get;
$this->post = $post;
//preset the view layer as an array
$this->view = array();
}
public function __destruct()
{
//extract variables from the view layer
extract($this->view);
//render the view to the user
require_once('view/'.$this->get['controller'].'_view.php');
}
}
class model_landing extends class_mysqli
{
public function __construct
{
echo "landing model";
}
}
class class_mysqli
{
public function __construct
{
echo "mysqli";
}
}
I don´t know, but I think you are missing brackets.
There
public function __construct
{
echo "landing model";
}
should be
public function __construct()
{
echo "landing model";
}
Related
If you have an abstract class, is there a way to keep a counter inside the abstract class to count how many times it's used?
Because if I do this:
abstract class abstractClassName {
private $counter = 0;
public function __construct() {
$this->counter++;
}
public function outputCounter() {
echo $this->counter;
}
}
class someExtension extends abstractClassName {
public function __construct() {
parent::__construct();
}
}
class someExtensionTwo extends abstractClassName {
public function __construct() {
parent::__construct();
}
}
and then
$class = new someExtension;
$class->outputCounter();
$class2 = new someExtensionTwo;
$class2->outputCounter();
I get 1 twice, yet I was expecting to get 1 and then 2 on the last call, and I'm getting confused over how it's all meant to work.
Edit: changed code to reflect the real code more :)
If you are wishing to keep track of how many time the class AbstractClassName has been instantiated, you will need to make use of static variables -- so that the value of $this->counter is persistent, for example:
abstract class abstractClassName
{
private static $counter = 0;
public function __construct() {
self::$counter++;
}
public function outputCounter() {
echo self::$counter;
}
}
class someExtension extends abstractClassName
{
public function __construct() {
parent::__construct();
}
}
class someOtherExtension extends abstractClassName
{
public function __construct() {
parent::__construct();
}
}
$class = new someExtension;
$class->outputCounter();
$class2 = new someOtherExtension;
$class2->outputCounter();
Which would result in an output of: 1 & 2.
i have probably a really easy problem, but i dont know how to fix it now. Maybe i just forgot something, but i need your help.
I have model:
<?php
class Model
{
protected $storage;
public function __construct()
{
$this->storage = $_SERVER["DOCUMENT_ROOT"] . "/mvc/images/";
if(!file_exists($this->storage))
{
mkdir($this->storage, 0777);
}
}
public function storageHandler()
{
if(count(glob($this->storage."/*")) === 0)
{
echo "Žiadne kategórie";
}
else
{
$iterator = new DirectoryIterator($this->storage);
return $iterator;
}
}
}
?>
And model Category, which is inherited from Model.
<?php
require_once($_SERVER["DOCUMENT_ROOT"] . "/mvc/model/Model.php");
class Category extends Model
{
private $photos_count;
public function __construct($data)
{
if(isset($data))
{
$gallery_path = $this->storage . $data;
if(!file_exists($this->$storage .$data))
{
mkdir($tihs->storage . $data, 0700);
header("Location: /mvc/" );
}
else
{
echo "Kategória už existuje.";
}
}
}
}
?>
I would love to use $storage variable from Model in my Category class. How should I do that? I know some way, but it's not gonna be the best one. Is there any solution that will make this good way?
besides Ray's answer you need you use parent::__construct() in your category class like so
class Category extends Model
{
private $photos_count;
public function __construct($data)
{
parent::__construct();
//rest of the code
The protected property $storage is available to your child class, but $this is spelt wrong in your examp:
mkdir($tihs->storage . $data, 0700);
It should be:
$this->storage ...
Also, as notedby mamdouh, you need to call the parent constructor from the child to initialize:
public function __construct($data)
{
parent::_construct();
...rest of code...
I have this code and i´m trying to use a object
<?php
class Controller {
public $_view;
public function __construct() {
$this->_view = new View();
return $this->_view;
}
}
class View {
public $_params = array ();
public function set_params($index_name,$valores) {
$this->_params[$index_name] = $valores;
}
public function get_param($index_name){
return $this->_params[$index_name];
}
}
?>
i would like to do this:
class Index extends Controller {
public function index() {
$model = Model::get_estancia();
$usuarios = $model->query("SELECT * FROM usuarios");
$this->_view->set_params(); // cant be used.
$this->load_view("index/index");
}
}
i would like to use the set_parms function.
but i can't see the View Function, then i can not use.
Can someone explain and advise me a good and safe way?
Correction from Phil: If a __construct() method isn't found, PHP will revert to legacy constructor syntax and check for a method with the same name as the object. In your case the method index() is being treated as the constructor, and is preventing the parent's constructor from loading the view object into the $_view property.
You can force a class to inherit a parent's constructor by defining __construct() in the child and calling the parent's constructor:
public function __construct() {
parent::_construct();
}
Here is the fixed code:
<?php
class Controller {
public $_view;
public function __construct() {
$this->_view = new View();
return $this->_view;
}
}
.
class View {
public $_params = array ();
public function set_params($index_name,$valores) {
$this->_params[$index_name] = $valores;
}
public function get_param($index_name){
return $this->_params[$index_name];
}
}
.
class Index extends Controller {
public function __construct() {
parent::__construct();
}
public function index() {
$model = Model::get_estancia();
$usuarios = $model->query("SELECT * FROM usuarios");
$this->_view->set_params(); // cant be used.
$this->load_view("index/index");
}
}
I have the following PHP code as chain of resposibility, I am using PHP5.4.9.
abstract class Logger
{
protected $next;
public function next($next)
{
$this->next = $next;
return $this->next;
}
public function run(){
$this->invoke();
if(null!=$this->next){
$this->next->invoke();
}
}
abstract public function invoke();
}
class EmailLogger extends Logger
{
public function invoke()
{
print_r("email\n");
}
}
class DatabaseLogger extends Logger
{
public function invoke()
{
print_r("database\n");
}
}
class FileLogger extends Logger
{
public function invoke()
{
print_r("file \n");
}
}
$logger = new EmailLogger();
$logger->next(new DatabaseLogger())->next(new FileLogger());
$logger->run();
the expect output is:
email
database
file
but the actually output:
email
database
I hope to implement chain of resposibility design pattern by PHP language, one abstract class and three or more classes to do something as a chain. but only the first two object works.
Anyting missing? Or PHP can not use this coding style under PHP5.4.9?
Thanks.
Replace
public function run() {
$this->invoke ();
if (null != $this->next) {
$this->next->invoke();
}
}
With
public function run() {
$this->invoke ();
if (null != $this->next) {
$this->next->run ();
}
}
please try $this->next->invoke() change $this->next->run()
I have an abstract base Controller class and all action controllers are derived from it.
Base Controller class at construction initializes View object. This View object is used by all action controllers. Each action controller have different dependencies (this is solved by using DI container).
The problem is that base Controller class also needs some dependencies (or parameters),
for example, path to view folder. And the question is - where and how to pass parameters to base Controller class?
$dic = new Dic();
// Register core objects: request, response, config, db, ...
class View
{
// Getters and setters
// Render method
}
abstract class Controller
{
private $view;
public function __construct()
{
$this->view = new View;
// FIXME: How / from where to get view path?
// $this->view->setPath();
}
public function getView()
{
return $this->view;
}
}
class Foo_Controller extends Controller
{
private $db;
public function __construct(Db $db)
{
$this->db = $db;
}
public function barAction()
{
$this->getView()->some_var = 'test';
}
}
require_once 'controllers/Foo_Controller.php';
// Creates object with dependencies which are required in __construct()
$ctrl = $dic->create('Foo_Controller');
$ctrl->barAction();
This is just a basic example. Why is the $view private? Is there a good reason?
class View {
protected $path;
protected $data = array();
function setPath($path = 'standard path') {
$this->path = $path;
}
function __set($key, $value) {
$this->data[$key] = $value;
}
function __get($key) {
if(array_key_exists($key, $this->data)) {
return $this->data[$key];
}
}
}
abstract class Controller {
private $view;
public function __construct($path)
{
$this->view = new View;
$this->view->setPath($path);
}
public function getView()
{
return $this->view;
}
}
class Foo_Controller extends Controller {
private $db;
public function __construct(Db $db, $path)
{
// call the parent constructor.
parent::__construct($path);
$this->db = $db;
}
public function barAction()
{
$this->getView()->some_var = 'test';
}
public function getAction() {
return $this->getView()->some_var;
}
}
class DB {
}
$con = new DB;
$ctrl = new Foo_Controller($con, 'main');
$ctrl->barAction();
print $ctrl->getAction();