Zend and static class properties - php

I'm trying to assign a value to a static class property when defining it:
namespace Base;
abstract class Skeleton {
protected static $entityManager = \Zend_Registry::get("EntityManager");
...
}
When I try to execute this code I get this error:
Parse error: syntax error, unexpected '(', expecting ',' or ';' in /var/www/
somewhere/application/models/Base/Skeleton.php on line 6
If I just assign a simple string value to it:
protected static $entityManager = "string";
Everyting is fine. Am I doing something PHP can't handle? If so, how to solve this?

You can't put code that needs executing as a class variable, static or not.
Think about it, at which point does Zend_Registry::get("EntityManager") get executed, it can't be executed when the class is created because you have set it as static.
Even if it was not static, when does Zend_Registry::get("EntityManager") get run? When the object is instantiated or once? It needs to be put in a function inside the class.

Class properties may not depend on data that has to be evaluated at runtime:
[Class member variables] may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.
Add a setter and set the value during bootstrap.

Related

Passing an object property into a closure in PHP

I am trying to pass an object property into a closure (that's within a method of that object), like so:
class Entity extends ControllerBase {
private $view;
private $events;
public function print($tid) {
self::loadView($tid);
self::loopView();
return (new StreamedResponse(function() use ($this->events){
...
}
}
}
The $events property gets instantiated in the loopView() method. This seems like it should work to me, but I get this error:
ParseError: syntax error, unexpected '->' (T_OBJECT_OPERATOR), expecting ',' or ')' in ...
It seems to be saying it doesn't expect there to be an object referenced in use. I don't know why this isn't valid, and after some googling, I couldn't find anything referencing my specific problem.
In PHP 7.1.7, is it possible to do this, and if so, what is the correct syntax?
You can just use $this->events in the closure without a use statement.
See "Automatic Binding of $this" in the anonymous function documentation.
As of PHP 5.4.0, when declared in the context of a class, the current class is automatically bound to it, making $this available inside of the function's scope.
For example: https://3v4l.org/gYdHp
As far as the reason for the parse error, if we disregard the specific $this case,
function() use ($object->property) { ...
doesn't work because use passes variables from the parent scope into the closure, and
$object->property is not a variable, it is an expression.
If you need to refer to an object property inside a closure, you either need to use the entire object, or assign the property to another variable you can use. But in this case you don't have to worry about that since $this is special.

You can't run a function when defining an object property?

The code in question...
class MyClass
{
public $template_default = dirname(__FILE__)."/default.tpl";
}
Why do I get the following error when I try to use the dirname() function when defining an object property?
Parse error: syntax error, unexpected '(', expecting ',' or ';' in ...
blah blah blah
I guess object properties are not like PHP variables.
That's right. From the docs:
This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.
Since dirname is a run-time function, it should be called in the constructor of the Object. So, set $template_default in the object constructor:
class MyClass {
public $template_default;
public function __construct(){
$this->template_default = dirname(__FILE__). "/default.tpl";
}
}
If you are using PHP 5.6, you can do the following:
class MyClass
{
public $template_default = __DIR__."/default.tpl";
}
PHP 5.6 allows simple scalar math and string concatenation in initialization now (docs), and __DIR__ is the same thing as dirname(__FILE__).
Otherwise, Drakes' answer is correct.

How to call method in class variable?

Say I want to set a class variable equal to (to keep things simple):
public $variable = strtolower('Dog');
When I try to do anything like this, I get: syntax error, unexpected '(', expecting ',' or ';' ...
I'm sure this is an amateur mistake, but I've searched the forum and Google and cannot find an answer to this anywhere. How can I call a built-in (proper terminology?) method within a class variable?
Thank you.
You can initialize class properties to constant values, but not call a function. You can however do that within a constructor.
class Test {
public $var1 = 'Dog'; // <-- This is allowed
public $var2 = strtolower('Dog'); // <-- This is not allowed
public function __construct() {
$this->var2 = strtolower('Dog');
}
}
From the docs:
This declaration may include an initialization, but this
initialization must be a constant value--that is, it must be able to
be evaluated at compile time and must not depend on run-time
information in order to be evaluated.

Php Array Elements Referenced From Another Array Inside a Class

Inside a class I have 2 associative arrays. I am trying to call elements from one array to be used in another (kind of master) array.
I would like to ask whether the following can be done, or can't, or what I'm doing so wrong;
Please note, the arrays are examples.
class ProductData {
private $texture = [0=>'Cream', 1=>'Powder', 2=>'Liquid', 3=>'Paste', 4=>'Solid'];
private $food = ['type'=>'Pasta', 'info'=>[1=>'750gm', 2=>'$4.50', 3=>$this->texture[4]],
'type'=>'Soup', 'info'=>[1=>'500ml', 2=>'$7.60', 3=>$this->texture[2]]];
// Constructor, Function(s) to access the $food array...
}
Well I have found out the hard way that this cannot be done. I receive a syntax error;
syntax error unexpected '$this' (T_VARIABLE).
If I replace the $this with $texture, I receive the same error;
syntax error unexpected '$texture' (T_VARIABLE).
I'm thinking that this cannot be done, or I'm doing something very wrong, or both.
If this can be done, any assistance is very much appreciated.
Thanks,
njc
class ProductData {
private $texture;
private $food;
function __construct(){
$this->texture = [0=>'Cream', 1=>'Powder', 2=>'Liquid', 3=>'Paste', 4=>'Solid'];
$this->food = ['type'=>'Pasta', 'info'=>[1=>'750gm', 2=>'$4.50', 3=>$this->texture[4]],
'type'=>'Soup', 'info'=>[1=>'500ml', 2=>'$7.60', 3=>$this->texture[2]]];
//other construct stuff
}
}
You can only use constant values to define property values outside class methods. So in your case, you cannot use the $this variable, as it references the current object instance.
You should move the initialisation to the __construct (which is really what is meant to be for)
Check out the documentation:
This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.

Error while assigning a public propery

function CharField($len)
{
return "VARCHAR($len)";
}
class ArticleModel extends Model
{
public $name = CharField(100); // Error Here
}
When I assign a public property like this with a returned value from a function, it throws the error:
PHP Parse error: syntax error, unexpected '(', expecting ',' or ';' in /var/www/test/db.php
What can the reason be?
You can only initialize properties with constants:
http://www.php.net/manual/en/language.oop5.properties.php
[Properties] are defined by using one of the keywords public, protected, or private, followed by a normal variable declaration. This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.
So indeed, initialize them in your constructor.
Initialize the value in your constructor
According to the manual you can only assign a constant value when instantiating a class property.

Categories