0

I read the answer to this question but it led to more questions: PHP variables reference and memory usage

In short, I have a project where I'm trying to loop through a multidimensional array to grab one value before continuing on with either the process or the loop. It'll be easier to explain in code:

// Demo variables
$this->content['alias1'] = ('object' => new someObject; 'info' => array('type' => 'abc'));
$this->content['alias2'] = ('object' => new someObject; 'info' => array('type' => 'def'));
$this->content['alias3'] = ('object' => new someObject; 'info' => array('type' => 'abc'));

... that's incredibly simplified, but it gets the point across. I want to loop through that and find all of the 'types' that are 'abc' - what's the easiest way to do it? I had something like this

foreach($this->content as $alias => $data) {
    if ($data['info'] != 'abc') {
       break;
    }

    // Do actual "abc" things
}

But I'm trying to write all of this code as memory-conscientious as I can. I feel as though there's probably a more efficient way to do this.

I was thinking that when the objects are loaded (this is essentially a config file), it would assign a reference to another variable, something like

$this->types->$type =& $this->content['alias1'];

for each. In the question referenced above, it said that PHP uses copy-on-write with references - if the reference is only read, never written, would this be an efficient way to be able to access the object? I was also thinking that maybe I could just store the array key name in the $this->types->$type array.

Community
  • 1
  • 1
Josh Toth
  • 754
  • 9
  • 23

2 Answers2

2

Copy-on-write means that PHP will automatically create a reference for you, provided you don't write to the target variable. If you write, it will copy the original value, and modify the copy instead. Bottom line is: you don't need to manually assign by reference in this case, you can just use a regular assignment:

$this->types->$type = $this->content['alias1'];

As long as you're just reading from $this->types->$type, it will be pointing to the same value in memory as $this->content['alias1'].

bfavaretto
  • 71,580
  • 16
  • 111
  • 150
  • Oh, now that's interesting. I didn't know that! Just to clarify, using `=&` and `=` would essentially be the same until the second is modified? – Josh Toth Jul 18 '13 at 15:30
  • Not sure if they're technically the same, I believe I heard you even use *less* memory when you don't manually create a reference. – bfavaretto Jul 18 '13 at 15:34
  • 2
    @JoshToth A good reference (haha) on this is http://php.net/features.gc.refcounting-basics – bfavaretto Jul 18 '13 at 15:44
  • interesting. And the read will come in handy! (nice pun, too :P ) – Josh Toth Jul 18 '13 at 16:26
1

PHP does copy on write for most of variables you pass around as arguments. Anyways, that's what my experiments led me to believe (even if you can break this in special cases). So, if you just need to loop and you don't play with references and such... you'll be safe.

But there's a way to check. Using the following 2 functions:

Use these two functions inside your code and check how your memory consumption changes as your code execution advances. This way, no matter what funky things you do with PHP, you'll easily tell if PHP is still doing copy-on-write or has done the copy for you.

CodeAngry
  • 12,760
  • 3
  • 50
  • 57
  • Haha yeah I was thinking of checking memory usage... I'm just lazy and thought maybe someone who knew more than I would be able to enlighten me :P – Josh Toth Jul 18 '13 at 15:29
  • @JoshToth In theory, as long as you just loop the arrays with no references, you're safe 99%. But if you are so *'memory-conscientious'* you have to get ready to get your hands dirty with memory usage tracking. – CodeAngry Jul 18 '13 at 15:41
  • good point. It's just that I'm at work right now and I had the idea this morning in the shower and wanted to know right away :P I shouldn't have said lazy, I should have said impatient. – Josh Toth Jul 18 '13 at 16:25