Reputation: 725
I'm working in Magento right now and am having a problem with variable scope. I have two files that are displaying something on a wish list. I need to pass a variable between those two files, which I can successfully do, the problem I'm having is that the two files run in a loop and I can't change those values. The basic code we're using is as follows: File 1:
global $var1;
//$var1 = '';
if($condition == true){
$var1 = 'string';
}
The other file echoes out $var1 correctly, giving me 'string'. The file then gets looped through again and repeats the process. The problem that I'm having is that if I uncomment that second line to reset the variable, it always stays an empty string. The if statement gets triggered for sure, the variable just doesn't get set. Am I misunderstanding how globally accessible variables work in php?
Upvotes: 1
Views: 4995
Reputation: 138
Adding to Mattihias' very detailed answer, if you do end up using the registry (not something to overuse), make sure you remove the entry from the registry as soon as it's not needed to keep it clean.
Mage::unregister('registry_key')
Upvotes: 1
Reputation: 1734
If you want to do this in a Magento way, you should connect the information to an object.
Without knowing any specifics we can't be sure but there is a good chance that your $var1
value can be logically connected to either the wishlist, a wish list item or something connected to them (like the customer or the products).
Having said that, there are different ways you can pass information around between Magento layout template files (what you basically want to do). I can't give you specific code as I don't know what you want to do exactly, but I can give you some options:
Block classes: every .phtml file has a $this
object. This means that your template file is rendered in the context of a object. The object is an instance of a block class. The layout XML files define which block class is used for this specific block. Learn more about it in the intro to layouts.
If the information in $var1
is used solely for presentation purposes in these blocks, you could store the information in one of the block objects itself. As the blocks are structured in a hierarchy (and you use a loop), you may consider to use a parent block for storing the information. You can get the parent block by using $this->getParentBlock()
. If you have found your object, you can call $block->setYourVariableName('value')
to save the value and $block->getYourVariableName()
to read it again. You also can access child blocks via $block->getChild('block_name')
or their data using $block->getChildData('your_variable_name')
. Find out more useful methods in the API documentation.
Model singletons: Another way to do this would be a singleton model. A singleton ensures that only exactly one instance of a certain class exists. This way, you can always access the very same object and share the data. Perhaps this won't be the perfect solution for you as you would have to create a new model class just for storing that small information bit.
On the other side, there are enough use cases where building a separate model makes sense. Again, as I don't know what you are you doing, you may be perfectly fine creating a model. You still can decide wheter you want to store the model as part of a block or access it using a singleton. If you want to use a singleton, refer to this article by Alan Storm, section "Magento’s Singleton Pattern".
Registry: I would use this as a kind of last resort. The registry is a central and global "store this information for me / get me this information" object. It's easy to use but you should avoid this wherever possible if you want to embrace best practices. (Some trivia: the singleton implementation of Magento actually uses the registry but hides the details from you.)
Please consider other options before doing this as you don't want to stuff the registry with loads of tiny information bits. If you want to use it, again have a look at Alans article.
Upvotes: 3