Reputation: 28742
I have the following code.
function up() {
$runafterupdate = [];
Schema::connection('exitproducts')->create('exitcontrol_carmanager_manager', function($table)
{
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('code');
$runafterupdate['code'] = true;
$table->timestamps();
});
}
if(isset($runafterupdate['code'])) {
echo "it worked!";
}
}
And i'm used to JavaScript where you can alter the values of the parent scope, but aparently php follows different rules. I've tried reading through http://php.net/manual/en/language.variables.scope.php but I really don't want to use globals.
Is there a way to alter the variables in the parent scope with php or is my only resort in this case a global variable?
Upvotes: 1
Views: 1320
Reputation: 28742
2021 update courtesy of George
It's no longer necessary. For searchers in the future: If you use the new (PHP>=7.4) "arrow function" notation for anonymous functions, variables in the parent are automatically accessible to you by-value. No use tag needed. php.net/manual/en/functions.arrow.php
After some more digging... why do I always find the answers AFTER I post a question...
Using the use clause on the function you can use the variables you declare there in the "child" scope. That this isnt highlighted in the scope documentation in php docs beats me.
Extracted from Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?
Extending the scope of variables into anonymous functions
$foo = 'bar';
$baz = function () use ($foo) {
echo $foo;
};
$baz();
After some fiddling I found i can't directly modify array variables. Any modifications stay in the function scope but dont lift over to the parent scope.
I made a simple holder object with setters and getters to get it to work.
function scop1() {
/** simple class to hold vars **/
class holder {
public $held = [];
/** setter **/
function update($what, $with) {
$this->held[$what] = $with;
}
/** getter **/
function get($what) {
if(isset($this->held[$what])) return $this->held[$what];
else return null;
}
}
$var = new holder();
/** works **/
$var->update('hello','bye');
$x = function() use ($var) {
/** modify parent scope **/
$var->update('hello','hello');
};
/** call anomynous function **/
$x();
/** it should say hello hello in held **/
var_dump($var);
}
scop1();
live sample: http://sandbox.onlinephpfunctions.com/code/d7464356c0712f2606b0f70ab952be4d782374dc
Upvotes: 2
Reputation: 1183
Using a Closure with &
will do the trick.
function test()
{
$var = 20;
$anonymous = function () use (&$var) {
$var++;
};
$anonymous();
echo $var; // 21
}
If you just want to pass just the value, use closure without &
$anonymous = function () use ($var) { ... }
Upvotes: 2
Reputation: 1890
If this function is inside a class, I don't see a problem if you declare your variable as public, private or protected ( I would go with private and create set/get functions for this variable if necessary). After that you can do $this->runafterupdate = true
inside your anonymous function. If your function is not inside a class I would go with globals, but I really don't suggest that.
Hove you tried with the use
keyword`?
Upvotes: 1
Reputation: 9442
You have an anonymous function, declare $runafterupdate
as a private array in your class and in the anonymous function use $this->runafterupdate
then check it. I`m guessing you are using Laravel
class Demo
{
private $runafterupdate;
...
public function up() {
Schema::connection('exitproducts')->create('exitcontrol_carmanager_manager', function($table)
{
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('code');
$this->runafterupdate['code'] = true;
$table->timestamps();
});
}
if(isset($this->runafterupdate['code'])) {
echo "it worked!";
}
}
...
}
This should work, if I`m not mistaken I had a similar issue
Upvotes: 0