7

ok what im trying to do is makeing something so i can call it like $this->model->users->getInfomation('name'); or something similer on my framework but php give me a strict standards Creating default object from empty value

protected function model($model)
{
    $path = "features". DS ."models". DS . $model .".php";
    require $path;

    $class = 'Model'. ucfirst($model);
    $this->model->$model = new $class;
}

can we make it so it will somehow fit in the standards ?

edit*

this function is in class Application so i can extend them from our controller like blog Extends Application then call something like $this->model->blog will get something like what im doing above, when i do something like

protected function model($model)
{
    $path = "features". DS ."models". DS . $model .".php";
    require $path;

    $class = 'Model'. ucfirst($model);
    $this->$model = new $class;
}

yes the above code works fine $this->blog->getSomething();, but somehow i want to make them in a group, like the question above, so if we want to get something like $this->model->blog->getSomething();

Thanks for the time.

Adam Ramadhan

Adam Ramadhan
  • 22,712
  • 28
  • 84
  • 124
  • I don't really know what are you trying to achieve. You want to model be automatically created when you calling `$this->model->[modelName]` ? – Radek Benkel Feb 01 '11 at 08:12
  • yes but the problem is maybe because of the $this->model is empty, i haven't made it anywhere. cant we just add that ? – Adam Ramadhan Feb 01 '11 at 08:16

5 Answers5

7

It's hard to see what you're actually doing wrong with that code alone. I've made some very simple code to reproduce the error:

<?php
$bar = 42;
$foo = null;

$foo->bar = $bar;

The reason it gives this warning, is that you're assigning values the "object way", but you're assigning it to a variable that isn't an object. By doing this, the Zend engine actually creates an object for $foo, which is an instance of StdClass. Obviously, 9 out of 10 times, this isn't what you want to do, so PHP provides a helpful message.

In your case: $this->model isn't an object (yet). If you want to get rid of the error, just do:

if( !is_object( $this->model ) ) {
    $this->model = new StdClass;
}
$this->model->$model = new $class;

Cheers.

Berry Langerak
  • 18,561
  • 4
  • 45
  • 58
  • yeah this one work, but if( !is_object( $this->model ) ) is giveing me an error $this->model not found, if i remove the is object it works fine!. anway what is a std class ? – Adam Ramadhan Feb 01 '11 at 08:34
  • 1
    You can find more information on that here at stackoverflow: http://stackoverflow.com/questions/931407/what-is-stdclass-in-php If you haven't defined $this->model, perhaps it is time to do so, instead of relying on all sorts of magic? – Berry Langerak Feb 01 '11 at 09:53
  • anyway after doing some research im using this for now, ill change the answer if there is a better one :D thanks. – Adam Ramadhan Feb 05 '11 at 07:21
2

You must use __get magic method - http://php.net/manual/pl/language.oop5.magic.php

You can achieve what you're looking for doing something like that:

<?php
class ModelCreator
{
    private $_modelsCreated = array();
    public function __get($model)
    {
        $class = 'Model'. ucfirst($model);
        //avoid creating multiple same models
        if (!array_key_exists($model, $this->_modelsCreated)) {
            $path = "features". DS ."models". DS . $model .".php";
            require_once 'modeluser.php';
            $this->_modelsCreated[$class] = new $class;
        }
        return $this->_modelsCreated[$class];
    }
}

class MyClass
{
    private $_model;

    public function __construct(ModelCreator $model)
    {
        $this->_model = $model;
    }

    public function __get($name) 
    {
        if ($name === 'model') {
            return $this->_model;
        }
    }
}  

$myClass = new MyClass(new ModelCreator());
$userModel = $myClass->model->user; // will return a class of ModelUser

But you should avoid magic like above -> better approach is to do it that way:

//model creator is an instance of model creator
$this->modelCreator->getModel('user'); // now you know what exactly is happening
Radek Benkel
  • 8,278
  • 3
  • 32
  • 41
  • thanks singles! yes it work too!, im waiting for a simpler solution. – Adam Ramadhan Feb 01 '11 at 08:39
  • If you want models to be created dynamically at your request and use properties instead of methods to retrieve them I doubt, is there simpler solution. – Radek Benkel Feb 01 '11 at 08:43
  • 1
    there is no simpler solution there is a design pattern that handles unique object instances and it is called a multiton (something like this model creator here).You can call it a collection of singletons. Stick to the book, trying to makes things simpler than they are might can create strange behavior, as you've already found out.Good example singles. – Catalin Marin Feb 01 '11 at 09:13
  • That's not the reason for his error message though. I do agree that this code is actually better than the one that he's using right now, although a simple Registry would do for his situation just as well? – Berry Langerak Feb 01 '11 at 09:56
0

In addition to Berry Langerak's answer

is_object will still trigger the strict check since it assumes there is 'something' in $this->model. isset is a better approach

if( !isset( $this->model ) ) {
    $this->model = new StdClass;
}

$this->model->$model = new $class;
Eric Herlitz
  • 25,354
  • 27
  • 113
  • 157
0

Must use double $'s

$this->model->$$model = new $class;
yoda
  • 10,834
  • 19
  • 64
  • 92
  • well as i know $$ means like this $this->model->$blog ? so it give us an error that $blog doesnt exist. what im looking for is something that can give me $this->model->blog from $this->model->$model; but the problem is $this->model i haven't made anything to this. please correct me if i am wrong. – Adam Ramadhan Feb 01 '11 at 08:15
  • Also, $$ means that where you have $$model, it will stick the name of the variable (e.g. if $model is "person", it will be $this->model->person). Tested and working. – yoda Feb 01 '11 at 08:24
0
if( !is_object( $this->request ) ) {
        $this->request = new StdClass;
    }
    if(!property_exists($this->request, 'method')) {
        $this->request->method = new StdClass;
    }
    // How is this request being made? POST, DELETE, GET, PUT?
    $this->request->method = $this->_detect_method();
Taghouti Tarek
  • 104
  • 1
  • 10