Objects passed by reference/alias vs return

I like the “skinny controllers” approach. Let’s say your model has a Content object that sets content, which is then injected into the view. In your controller you could do either of these (simplified example):

// Option 1, returns $content
$content = $model->getPageContent('contact');

// Option 2, doesn't return $content but the result is the same
$model->loadPageContent('contact');

// Option 1 and 2 both give the same result
new View('contact', $content);

Unless a native PHP function requires it, I pretty much never use references. In the above I typically use option 1 but have found myself using option 2 when it comes to controllers as it makes them skinnier.

It’s a small point but I’m curious at to what your opinion is on this. Do you think references are okay for this or do you think having it a little more verbose and readable is better?

I’m responding without regard to controllers and models here…

Option 2, if it truly does have the same result as Option 1, must be loading a variable or property called “content” someplace, and it is implied that it is either global or at least of class-scope and not local method scope. Due to the broader scope, I would opt for Option 1. Of course, all this based on what I can see. Or perhaps you have just hard-coded where you are writing the content and are not saving it off to a var or property.

“Option 3” seems to be passing $content by ref (per the call and what you said) and then also simultaneously returning a new object. That seems convoluted–but could be necessary depending on context. I myself would avoid using option 3 unless for some reason it was “less convoluted” than other methods you could use.

Option 2 could be “skinnier” but it seems by using that option you have pre-committed where the content will be written and you lose the flexibility of where you will write content. With Option 1, you have the ability to place that content wherever you like.

And another thought about Option 3 is that it locks you in. It is rigid. But I realize I speak without knowing your implementation of views. What if you wanted a view that included ‘contact’ but also ‘customer’ data/information?

I don’t know if you showed enough code to illustrate how option 2 is used. From your sample the only way option 2 can possibly work is by declaring $content global, which is very bad here and I would never use it.

Also, I tend to dislike methods beginning with load because they don’t describe enough what they do. Load page content but where from and where to? We know the content is loaded somewhere somehow but we don’t know where it ends up, which is the most important thing. The only place I find load... methods acceptable is internal (private/protected) methods whose purpose is for example to load content from a database to a cache, etc. - then load is an implementation detail that is meaningful in the context of internal class methods - but not outside to the public.

Sometimes, I use references to add some kind of data to existing data but only when the data structure is large and complex and I want to avoid duplicating it in memory just for the sake of adding something small. For example, I have an array of products with many fields describing each product and I want to add a calculated price in a foreign currency:

$currencyConverter->addForeignPriceToProducts($products);

$products is a reference argument in the method so the products array doesn’t have to be created separately just to add one price to each product. I think this is the only case I allow myself to use references but I try to keep my API and method names clear. Whereas in your code (option 2) as you presented it I have no idea what is going on, how the data goes from one place to the other.

@phpRob, @Lemon_Juice Thanks but you are right, my sample code was insufficient. I’ll re-phrase it and won’t use MVC as an example as it’s not really necessary.

I am not using globals; my question is really asking whether you rely on the way PHP 5+ uses object identifiers.

Perhaps this is better:

class A {
    public $foo;
    public function __construct() {
       $this->foo = 'bar1';
    }
}

class B {
    public function foo(A $a) {
        $a->foo = 'bar2';
        return $a;
    }
}

$a = new A;
$b = new B;
/*$a = */$b->foo($a);
// The line below echoes 'bar2' regardless of whether the line above is uncommented or not
echo $a->foo;

When you inject objects you don’t have to return them due to the way they work in PHP 5+ as linked above. I still explicitly return things anyway because I think it causes fewer headaches down the line and makes more sense when you revisit your code later on.

I’m not questioning why the above works like it does (there is a good explanation here in case anyone doesn’t know), I’m wondering if you ever use this feature, if so, when? Or do you always return them?

My original (garbled post) was really saying that I’ve found myself using the more concise version in controllers only just to make them a bit leaner – but now I am questioning my decision and feel that it’s better always return things.

I hope that makes more sense now!

So you are talking about the passing of objects by reference and whether you should “re-save them” when you get them back from a called function or method as a return value. I think it redundant and wasteful to save them a subsequent time; an additional unneeded assignment is getting executed, and going further, I don’t believe you should return an object that is modified in a function since it is passed-by-reference to begin with. Plus, you can save that opening for returning a return value to return something else that might be meaningful. Take PHP array functions. They modify arrays by ref, but will return a value of false if there is some failure. The confusing thing about your initial post is that none of your options 1-3 had to do with passing arguments by reference.

Your second example makes the problem clearer but I get a weird feeling it is somewhat theoretical, in other words I’ve never encountered it in my coding. The reason for this, I think, is that I believe using objects like this is bad practice - sometimes this would be justifiable but most of the time the problem should be solved differently.

I think one object should not change properties of other objects nor should it be allowed to. A slight improvement would be to make foo private and create a getter and setter for it but then we are only masking the problem. A better way would be not to construct objects as data collections to be manipulated by outside code but rather make them do specific tasks. Therefore, your don’t expose public properties and methods are not setThis(), getThis(), etc. but rather specific verbs like doThis(), fetchThat(), transformDataLikeThis(), saveData(), etc. An exception to this rule would be value objects, which are simply enclosures for data and don’t contain any programming logic. But from your theoretical example I can’t tell whether you are talking about value objects or service objects. See point 9 “Mixing Service Objects with Value Objects” at http://misko.hevery.com/2008/07/30/top-10-things-which-make-your-code-hard-to-test/

Your problem is also mutable vs immutable objects. You should decide whether you keep your objects mutable or immutable. In your example the $a object is clearly mutable and I think if a method changes an object’s value then it should not return it since this would be duplicated logic. But you should make the method name clear to represent this action like this:

$b->setObjectsFooToBar2($a);

You can find a similar situation in native DateTime object:

$dt = new DateTime;
$dt->modify('+1 day');  // this changes $dt object value

The difference is that you are changing another object’s value. Personally, I would avoid this and class A should not allow this. An example of a better solution would be to make class A expose a method for adding data, let’s say A is a collection of list items (but it could be anything else):

class A {
    private $listItems;

    public function __construct() {
        $this->listItems = ['Always present first item.'];
    }

    public function addItem($item) {
        $this->listItems[] = $item;
    }

    public function getItems() {
        return $this->listItems;
    }
}

class B {
    public function addBar2ItemToListObject(A $a) {
        $a->addItem('bar2');
    }
}

$a = new A;
$b = new B;
$b->addBar2ItemToListObject($a);

echo $a->getItems();

To make it even nicer you can use an interface to specify what kind of objects can be manipulated by addBar2ItemToListObject() so that it doesn’t have to be only A but also other objects with the method addItem():

interface itemCollection {
    public function addItem($item);
}

class A implements itemCollection {
    private $listItems;

    public function __construct() {
        $this->listItems = ['Always present item.'];
    }

    public function addItem($item) {
        $this->listItems[] = $item;
    }

    public function getItems() {
        return $this->listItems;
    }
}

class B {
    public function addBar2ItemToListObject(itemCollection $collection) {
        $collection->addItem('bar2');
    }
}

$a = new A;
$b = new B;
$b->addBar2ItemToListObject($a);

echo $a->getItems();
1 Like

I think it redundant and wasteful to save them a subsequent time; an additional unneeded assignment is getting executed, and going further, I don’t believe you should return an object that is modified in a function since it is passed-by-reference to begin with. Plus, you can save that opening for returning a return value to return something else that might be meaningful.

I don’t think performance would be a contributing factor here. I haven’t seen benchmarks but I’d imagine there is very little difference. I’m more thinking that it makes the code more readable. I can’t help thinking if a function is changing several objects and then returning another value it’s doing too much. I appreciate some PHP functions rely on this per your array example though.

I haven’t used any other scripting languages for years (since early 2000s at uni). Do other web scripting languages handles objects the same web as PHP?

Thanks for your input; this is why I posted to here others’ opinions.

I get a weird feeling it is somewhat theoretical, in other words I’ve never encountered it in my coding. The reason for this, I think, is that I believe using objects like this is bad practice

I agree with that; I’ve only ever felt the need to do it with a Content object (see below). Intuitively, it feels like bad practice to me too which is why I asked. The fact is though, you don’t need to return objects. I don’t understand the rationale for this as it seems too global-esque and wonder if Perl, ASP, etc do the same (I last used ASP in 2003!).

An exception to this rule would be value objects, which are simply enclosures for data and don’t contain any programming logic. But from your theoretical example I can’t tell whether you are talking about value objects or service objects.

Again, my crude examples have caused problems. I only used a public property to make the example simpler. I am referring to a value object per your point 9 link.

I have a single Content object that has a set($key, $value) method. Content is injected into the other classes (Models) which then set data using that function and that is then used by in the view. The models don’t need to return the Content object due to the way PHP works but I am asking if you think it is good practice to do so.

In your two examples you have chosen not to return $a. Is this how you would do it or are you just trying to improve my examples?

I enjoyed reading that part of your link but I’m not too concerned with how the classes are designed. I find that objects naturally fall into service or value objects anyway. The only hybrid ones are logger type objects that store logs and then perform functions such as writing those logs to the file system. And I guess your database connection object stores the last insert ID, etc.

Thanks for your input!

If I understand your description correctly, Content is a kind of collection object that accepts data via the set() method and saves them in its internal state. That is fine, there are many cases for this kind of usage, for example template engines usually accept data with a set or assign method on an object and then you can construct the whole template using the previously passed data. PDF and Excel libraries are another example - there is a much more complex set of methods to pass data to construct the final document but the basic idea is the same.

However, what worries me in your description is that you inject Content into other classes, which add data to it. This reduces flexibility and class reuse because the classes that add to Content (your Models) have too many responsibilities. For example, a model class may have one major responsibility, which is fetching data from a database. When you pass Content to it then you add another responsibility, which is filling the Content object in a specific way. What if you want to use that same Model class to fetch the same data but not for the page content but for constructing a PDF document? Sure, with some hackery you’ll be able to do that but I’d prefer to keep things separate. You’ve made you Model class dependent on Content - sometimes dependencies are a good thing but probably not where you can easily do without them.

If you have something like this:

$model->loadPageTitleIntoContent('contact', $content);
$model->loadPageBodyIntoContent('contact', $content);

I would prefer this:

$content->setTitle($model->getPageTitle('contact');
$content->setBody($model->getPageBody('contact');

or even a more generic way for structureless data collection:

$content->set('title', $model->getPageTitle('contact');
$content->set('body', $model->getPageBody('contact');

In other words I would let both Content and Model object just deal with only one task while I would wire the two together in an outside code. Let Model simply return data and then let the calling code do with the data what it considers appropriate. Model is now free and independent from Content.

I would not return $a, that is the point. In that example that would be redundant anyway, because I just passed $a as an argument so why would I need it returned? However, right now I cannot think of a use case for that code, just for adding data from models to a content object I would do what I wrote above in this post.

1 Like

Right, and agreed, the performance part doesn’t worry me either–yes, likely not a factor. Overall, in the end, I think we are dealing with preferences here as far as our discussion goes about passing objects by reference and how we implement return values to functions that receive objects by reference. Passing objects by reference has been with programming since the very beginning, since C and C++. Of course PHP uses it in its built-in functions and classes and JavaScript also uses it in client-side programming. Not just uses–but relies on–even desires. Why desires? “Code-re-use”, “flexible code”, “component-based code”. This is all about OOP which is a good thing. I say…use it all to your advantage. I understand also you need to do what is comfortable for you. If you don’t like passing a whole object into a function to get morphed or tweaked, you could just call three functions and pass 3 of the object’s properties for modification in three different function calls. But the work is likely closely related enough that it is intuitive (and maintainable!!) to do all three modifications in a single function call. Preference: you get to decide is the nice part.

1 Like

What if you want to use that same Model class to fetch the same data but not for the page content but for constructing a PDF document?

The model just sets the data. It doesn’t know what kind of view it will be used in (XML, TXT, HTML) though most of the time it is HTML. Since the view does the escaping I’ve never seen this as a problem. We actually had this discussion and few months ago, you and I, on my previous question, that the further you go into an application the less likely it is that a class would be reused.

I do like your third code example though and think this is probably the way to do it.

I would not return $a, that is the point. In that example that would be redundant anyway, because I just passed $a as an argument so why would I need it returned?

This really is the answer to my question — and it seems you concur with @phpRob. I think it’s maybe just my weird brain but not returning it seems too magic. However, you have pointed out, quite rightly, that the problem can be solved by having better function nanes.

$b->loadItems($a); // Not obvious what it is doing
$b->addBar2ItemToListObject($a); // Obvious what it is doing
$a = $b->addBar2ItemToListObject($a); // Obvious but verbose and works against the design of the language

Passing objects by reference has been with programming since the very beginning, since C and C++

I agree with everything you have said. My only gripe is with PHP objects it is implicit. It many cases, whether you add & or not when you pass the object won’t a difference. I know it’s my personal issue and this is how the language is designed. It just felt wrong to me so wanted to clarify its intended usage.

I work on my own and sometimes that makes following best practices difficult. You don’t get to bounce ideas off anyone or learn from another team member. So, I very much appreciate being able to hear your opinions.

Thanks!

1 Like

Of course, the model doesn’t know where the data will be used but it knows it will be used by an object with a set method. This creates a coupling between the two objects. Depending on the application this may or may not be a problem and I admit this pattern may be useful in certain situations. But when a solution without any coupling is easily available then I’d always go for it. Also, when passing Content to Model to me this looks like violation of the single responsibility principle.

Yes, we had that conversation but I meant the further up you go into an application the less likely it is a class would be reused - by up I mean the outer framework code. Models are actually on the other extreme - they are far down the application code and they are the ones that should be made for reuse :smiley:

You make I good point and I think I will stop injecting the Content object into the model.

I mean that library and framework classes (router, cacher, database, etc) definitely get reused and I would never inject something like a content object into those. I am referring to classes that are for a specific client’s site and would not typically get used elsewhere.

[quote=“DrQuincy, post:13, topic:292531”]I agree with that; I’ve only ever felt the need to do it with a Content object (see below). Intuitively, it feels like bad practice to me too which is why I asked. The fact is though, you don’t need to return objects. I don’t understand the rationale for this as it seems too global-esque and wonder if Perl, ASP, etc do the same (I last used ASP in 2003!).

[/quote]

For what it’s worth, this is how objects behave in almost every language and yes, it’s by design! An object is an instance, and that instance can be referenced anywhere throughout the script. It’s not really global because you can have different instances where and if you need them.

As an example of why this is useful, consider the DOM:

$document = new \DomDocument();

$body = $document->createElement('body');

$document->appendChild($body);
$h1 = $document->createElement('h1');

$body->appendChild($h1);

Without references, to add the h1 element to the body I’d have to do this:

$document = new \DomDocument();

$body = $document->createElement('body');

$document->appendChild($body);


$h1 = $document->createElement('h1');

$body->appendChild($h1);

//Remove body
$document->removeChild($document->firstChild);

//Add the updated version containing the H1
$document->appendChild($body);
1 Like

Now I realize I have a bit different idea of reuse when programming and we might not understand each other precisely. When I write a class I don’t try to think whether I will need to reuse it or not - I assume by default that I may reuse this class somewhere sometime and keep it in mind. Of course, specific-purpose model classes probably will never be reused outside a single project or even within but they will end up better quality (easier to read) when I assume so. I imagine I may need to reuse any class I write and try to make them as independent as possible, and only later relax this requirement if there is a really compelling reason - like performance or saving a LOT of redundant code.

Anyway, I think it’s better if we keep these discussions about best practices - and in practice everyone will decide for themselves how much to follow them. The programming world is not ideal and we make compromise at times :smiley:.

1 Like

That’s great, Tom, thanks for the example!

specific-purpose model classes probably will never be reused outside a single project or even within but they will end up better quality (easier to read) when I assume so

I’d say that’s pretty much how I do it too, though maybe not as strictly as you do. When I talk about injecting a content object I’m talking about those kinds of classes. For example, I recently has wrote a CRM class for a client that added leads to their Salesforce account using some custom workflow. The CRM class was never going to get reused but the cURL and JSON classes that were injected into it were/do. Hence, the content object was injected into the CRM class, though I appreciate your argument against that.

Thanks folks, it’s been educational.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.