Beware of the underscore
Have you ever tried using underscores (_) in your controllers variables that you are passing to the view using a combination of Controller::set() and compact()? Well, if you did, you must have realized that they never make it there, right? I haven’t submitted it as a bug yet but here it is:
class SandboxController extends AppController {
var $uses = null;
var $layout = 'sandbox';
function beforeRender(){}
function index()
{
$foo = 'foo';
$bar = 'bar';
$foo_bar = 'foobar';
$this->set(compact('foo', 'bar', 'foo_bar'));
$john = 'john';
$doe = 'doe';
$john_doe = 'john_doe';
$this->set(compact('john', 'doe'));
$this->set('john_doe', $john_doe);
}
}
Now, in your view:
echo $foo . "<br />";
echo $bar ."<br />";
echo $foo_bar ."<br />";
echo "<br /><br />";
echo $john ."<br />";
echo $doe ."<br />";
echo $john_doe ."<br />";
Finally, the returned output:

Anyone knows if that’s how it’s supposed to act?
Update: there is a way to actually get those variables intact. Thanks to Taylor for pointing it out.
$this->set(compact($foo, $bar, $foo_bar), false);
Trackbacks
Trackbacks are closed.


If you feed the set function with an array, the underscored words get camelCased. So your $foo_bar will be $fooBar. Camel cased variables are Cake’s coding standart and this is probably done with the intention when putting a data array from the Model::find() operation to set().
i encountered this problem at one time. i think i remember that the variables get sent to the view as fooBar. i just make a point of not using an underscore anymore.
@all: thanks for dropping by
@klevo: if that’s the case, then it should check if a model with that name exists first, no? would make more sense if you ask me.
@dave: i have a hard time changing my coding conventions to work around something that is not functioning correctly
I think they intend for things to work that way (I’m not sure why). For instance, if you create a controller called myController, and name your view myController.ctp, you’ll get a file not found error. You have to name the view my_controller.ctp. It seems to be a convention in cake.
@klevo: actually CamelCase and camelBack, Inflector::variable() transform your underscored_string in a camelBackedString.
@Jad: I think it would make more sense to make all vars have their names pimped by Inflector::variable();
Here is the work around.. Either set one variable at the time or when doing pass set pass false as second variable.
$this->set(’underscoredwords’, ‘ok’);
$this->set(array( ‘underscoredwords’ => ‘ok’, ‘cakestoprewritemyvars’ => ‘true ), false)
$this->set(compact(’underscoredwords’), false);
hope this help
@taylor: nice!! haven’t checked the code but that definitely fixes it.
I also noticed this “bug” and I know that I should not use compact with underscored vars.
Although it’s more convenient, I’ve always used $this->set(’varname’=>’varvalue’); For me it’s more clear.
the approach proposed from taylor luk - ya, it could do the job, but it is so complicated