0

I thought I was pretty comfortable with the fundamentals of OOP in a few languages like Python and PHP, but I got a bit confused trying to figure out what's going on in certain situations in CakePHP.

Say for example I'm in a controller called TestsController but I want to look up data from another controller, such as OthersController. I'd do something like this

$this->loadmodel('Other');
$this->Other->find('all');

I understand that $this is a reference to the object of the class you're in, and Other clearly refers to OthersController, but what exactly is Other? Is it some kind of initialization variable? An Object? Something else? Does $this->Other become an object itself? If so, how does PHP/CakePHP do this, or is it just something inherent of PHP that it just "knows" to do so.

I found this example of something called method chaining, but it looks like using one object to call many actions.

<?php
class MyClass{
    public $prop1 = "I'm a class property!";
}
$obj = new MyClass;
echo $obj->prop1; // Output the property   
?>

I understand with $obj you're accessing $prop1, but what's happening in CakePHP when there's something like $obj->SomeModel->action()?

If possible could you modify that little OOP example to mimic that of CakePHP?

Community
  • 1
  • 1
user2443591
  • 127
  • 4
  • 16

3 Answers3

1

In your example, $this->loadmodel('Other') populates $this->Other with the model object you asked for. So you can treat it as a typical object (call methods, access properties, etc.). You could even do this:

$this->loadmodel('Other');
$other = $this->Other;
$other->find('all');

$other is assigned a reference to $this->Other, so they will both act exactly the same.

As for chaining, let's say that $this->Other->find('all') returns another object of the type ResultSet, and the ResultSet class has the method getNumResults(). Chaining means you could do something like this:

echo $this->Other->find('all')->getNumResults();

As long as each method you're calling in the chain returns another object, you can keep calling the methods on that object.

Marty Penner
  • 228
  • 2
  • 16
  • Glad to hear it. I've updated my answer to include a chaining example. – Marty Penner Aug 13 '13 at 14:45
  • Can you see my response to the answer below by Jon. I asked him something similar to your response. Why wouldn't what I ask work? – user2443591 Aug 13 '13 at 14:50
  • As Jon said, the method `loadmodel()` doesn't return the model you asked for; it returns a boolean. You could do this: `$other = $this->Other; $other->find('all');`, as long as you've loaded the model first. – Marty Penner Aug 13 '13 at 14:56
0
$this->loadmodel('Other');
$this->Other->find('all');

I understand that $this is a reference to the object of the class you're in, and Other clearly refers to OthersController, but what exactly is Other? Is it some kind of initialization variable? An Object? Something else? Does $this->Other become an object itself? If so, how does PHP/CakePHP do this, or is it just something inherent of PHP that it just "knows" to do so.

Other does not refer to OthersController, it refers to an Other model. Cake automatically loads the model named Other inside OthersController (it infers the relationship from their names), but inside any other controller $this->Other is not available unless you explicitly load the model by calling $this->loadmodel('Other') first. This is what the snippet above does.

Even when the model is loaded by Cake, this is still done explicitly (even though it's transparent to you) inside the constructClasses method.

From the point that the model is loaded onwards, it is accessible through $controller->ModelName as any other object.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • So if it's loaded, can you do something like $other = $this->loadmodel('Other'); and then use $other->find('all') instead of $this->Other->find('all) – user2443591 Aug 13 '13 at 14:42
  • @user2443591: No. `loadmodel` does not return the model itself, it just returns `true`. – Jon Aug 13 '13 at 14:43
0

Adding to Jon answer, PHP frameworks do a lot of MAGIC.

I find myself learning about magic getter / setters, and much things like that.

For example, the Yii ActiveRecord, each row in database is an object.

So you, for example do this to load a record:

$user1 = User::model()->findByPk('1');

$user1->name = 'Jorge';
$user1->save;

So, it will take time until you start to actually comprehend what the framework is doing.

I bet that when you do $this->load->('model'); it fills something, it loads the model in some structure, maybe an array, and replacing the magic getters/setters you can actually say that when going for $this->modelName you actually are going to $this->modelsArray['modelName'].

An example without data validation:

class MyClass
{
  private $arrayExample = array( 'value1'=>123, 'value2'=>234);

  public function __get( $property )
  {
    if( array_key_exists( $this->arrayExample, $property )
      return $this->arrayExample[$property];
    return 'undefined';
  }
}

$class = new MyClass;
echo $class->value1; //outputs 123
echo $class->value0; //outputs undefined
JorgeeFG
  • 5,651
  • 12
  • 59
  • 92