Access a static variable in a class - php

The example below has a syntax error because of the following code:
"another_key" => [ 2 => self::$someStr ]
Using something such as:
"another_key" => [ 2 => "bar" ]
Is correct syntax. Is there any way to access $someStr instead of hard coding the string?
<?php
class Foo {
protected static $someStr = 'bar';
private static $arr = [
"some_key" => [ 1 ],
"another_key" => [ 2 => self::$someStr ]
];
}

You cannot access static variables inside of the declaration of other static variables. You can either declare a class constant or initialize it by accessing via a function. A class constant would look like this:
class Foo {
const someStr = 'bar';
private static $arr = [
"some_key" => [ 1 ],
"another_key" => [ 2 => self::someStr ]
];
}
Or using a function:
class Foo {
private static $someStr = 'bar';
private static $arr = [
"some_key" => [ 1 ],
"another_key" => [ 2 => null ]
];
private static function setKey(){
self::$arr['another_key'] = [2 => self::$somStr];
}
}
You'd then have to call Foo::setKey() at some point before accessing the variable.

If you want to access a property to set the value of another property you should be doing it in the class' constructor. Something like this:
class Foo {
protected static $someStr = 'bar';
private static $arr = [
'some_key' => [1]
];
public function __constructor()
{
self::arr['another_key'] = [2 => self::$somStr];
}
}
For this to work you will need to instantiate your class.
You can view some examples on property declarations in the PHP documentation.

Related

PHPSpec: function returning by reference

I updated Doctrine 2.5 to 2.6 in my project and phpspec is broken.
The function getEntityChangeSet() is now returned by reference. It seems not to be supported by phpspec.
$unitOfWork
->getEntityChangeSet($site)
->willReturn(['_dataParent' => [0 => 2, 1 => 3]]);
The response is
returning by reference not supported
the underlying function (doctrine/doctrine2) is
public function & getEntityChangeSet($entity)
{
$oid = spl_object_hash($entity);
$data = [];
if (!isset($this->entityChangeSets[$oid])) {
return $data;
}
return $this->entityChangeSets[$oid];
}
Do you know if it's possible to bypass this or change test for make it work?
The answer has been given on Twitter by #Pamilme
You have to mock UnitOfWork with Mockery. An example can be found here:
/** #var UnitOfWork|MockInterface $unitOfWork */
$unitOfWork = Mockery::mock(UnitOfWork::class);
$unitOfWork->shouldReceive('getEntityChangeSet')->withArgs([$productAttribute->getWrappedObject()])->andReturn([
'configuration' => [
['choices' => [
'8ec40814-adef-4194-af91-5559b5f19236' => 'Banana',
'1739bc61-9e42-4c80-8b9a-f97f0579cccb' => 'Pineapple',
]],
['choices' => [
'8ec40814-adef-4194-af91-5559b5f19236' => 'Banana',
]],
],
]);
$entityManager->getUnitOfWork()->willReturn($unitOfWork);
if you extends TestCase on your test class, you can also do something like:
$uow = $this->createMock(UnitOfWork::class);
$uow->method('getEntityChangeSet')->willReturn(['_dataParent' => [0 => 2, 1 => 3]);

Is it possible to print all called classes and functions in php?

If I have this example :
class A {
public function test(){
echo 'a';
}
}
class B {
public function test(){
echo 'b;
}
}
class C {
public function test(){
(new A())->test();
}
}
(new A())->test();
(new B())->test();
(new C())->test();
I want to get array with all called functions and classes, something like:
[
'A' => [
'function' => 'test',
'count' => 2,
'miliseconds' => 20,
'miliseconds_each' => [5, 15],
],
'B' => [
'function' => 'test',
'count' => 1,
'miliseconds' => 25,
'miliseconds_each' => [25],
],
'C' => [
'function' => 'test',
'count' => 1,
'miliseconds' => 30,
'miliseconds_each' => [30],
]
]
Notice: I want solution for whole framework not just bad workaround for this small example.
I would do like this, Make a base class and extends to update your analysis.
<?php
class Base{
static $data;
public static function analysis(){
return this::data;
}
function update($function){
if(isset(Base::$data[$function])){
Base::$data[$function] = ['count'=>Base::$data[$function]['count']+1,'function'=>'test'];
}else{
Base::$data[$function] = ['count'=>1,'function'=>'test'];
}
}
}
class A extends Base{
public function test(){
$this->update('a');
echo 'a';
}
}
class B extends Base{
public function test(){
$this->update('b');
echo 'b';
}
}
class C extends Base{
public function test(){
(new A())->test();
}
}
(new A())->test();
(new B())->test();
(new C())->test();
print_r(Base::$data);
?>
I know you can update code to get miliseconds and miliseconds_each
Live demo : https://eval.in/879998

Parent's class static variable different value for child's classes

Please, sorry for my English.
My problem:
abstract class Entity
{
protected static $fieldNames;
public static function getFieldsNames()
{
if (is_null(static::$fieldNames)) {
foreach (static::$fieldsMap as $name => $map) {
static::$fieldNames[] = $name;
}
}
return static::$fieldNames;
}
}
class User extends Entity
{
protected static $fieldsMap = [
'id' => [
// ...
],
'name' => [
// ...
],
'phone' => [
// ...
]
];
}
class Car extends Entity
{
protected static $fieldsMap = [
'id' => [
// ...
],
'brand' => [
// ...
],
'color' => [
// ...
]
];
}
print_r(User::getFieldsNames());
// ['id', 'name', 'phone'] - On first call it works as expected, but...
print_r(Car::getFieldsNames());
// ['id', 'name', 'phone'] :(
If I declare $fieldNames in User and Car classes work fine, but in real project I has tens of static variables such $fieldNames and hundreds of entity's
Is it possible to best solution?
Maybe create small repository class that will keep these static variables by entity's id? or another elegant way?
Thanks any Help!
$fieldNames is static so it's associated with the class itself and not with a specific object.
The class in this instance is "Entity".
Once you set it it is no longer null.

Syntax error when accessing static array with in class

public static $config = array(
'base_url' => '',
'environment' => '',
'database' => array(
'dbdriver' => '',
'dbhost' => '',
'dbname' => '',
'dbuser' => '',
'dbpass' => ''
),
I want to access the base_url key and assign it to a new static property $app but it is giving me syntax error of unexpected [
public static $app_path = self::config['base_url']; //unexpected [ error
You want to access variable so you have to add $.
self::$config['base_url']
Read some more about that here.
Unfortunately you can't assign any variable (even static) to other static property as you can see in linked manual page.
Like any other PHP static variable, static properties may only be initialized using a literal or constant; expressions are not allowed. So while you may initialize a static property to an integer or array (for instance), you may not initialize it to another variable, to a function return value, or to an object.
Read the manual:
Like any other PHP static variable, static properties may only be initialized using a literal or constant; expressions are not allowed. So while you may initialize a static property to an integer or array (for instance), you may not initialize it to another variable, to a function return value, or to an object.
Right here
And before you think this is a severe limitation, let me tell you why this is a blessed relief:
class Foo
{
public static $evil = array('bar' => 123);
public static $check = self::$evil['bar'];
}
Foo::$check;//all is well
But then, when you introduce late static binding (something we all love):
class Foo
{
public static $evil = array('bar' => 123);
public static $check = static::$evil['bar'];
}
class Bar extends Foo
{
public static $evil = 123;
}
Bar::$check;//OOOPS
TL;TR: statics are something like super-globals: you can initialize them with a constant expression, but they can't require state to be initialized, that would be inception madness
The way you've initilized your (static) properties, is not yet implemented in PHP
You can check this thread's explanation: https://stackoverflow.com/a/1633024/4098311
However, this is how i'm doing in my projects :
<?php
class YourClass {
public static $config = NULL;
public static $app_path = NULL;
public static $_INITIALIZED = FALSE;
public static init() {
if(!self::$_INITIALIZED) {
self::$config = array(
'base_url' => '',
'environment' => '',
'database' => array(
'dbdriver' => '',
'dbhost' => '',
'dbname' => '',
'dbuser' => '',
'dbpass' => ''
));
self::$app_path = self::config['base_url'];
self::$_INITIALIZED = TRUE;
}
}
// ....
// Your Stuf ...
// ....
}
YourClass::init();

php - Access parent class array in child class

class Settings {
public $constants = [
'database' => [
'APP_DB_HOST' => 'localhost'
],
];
}
class Constants extends Settings {
public $database = [
'APP_DB_HOST' => $settings->constants['database']['APP_DB_HOST'], // not working
];
}
I need to access parent class array values in child class. but this $settings->constants['database']['APP_DB_HOST'] is not working for some reason.
Here is the working solution
<?php
class Settings {
public $constants = [
'database' => [
'APP_DB_HOST' => 'localhost'
],
];
}
class Constants extends Settings {
public $database;
public function __construct(){
$database = [
'APP_DB_HOST' => $this->constants['database']['APP_DB_HOST'], // working
];
}
}
print_r(new Constants());
outputs:
Constants Object
(
[database] =>
[constants] => Array
(
[database] => Array
(
[APP_DB_HOST] => localhost
)
)
)
as per your comment,
if you want to do it in other class function, you can do that as well.
class Constants extends Settings {
public $database;
public function useParentHost(){
$this->database = [
'APP_DB_HOST' => $this->constants['database']['APP_DB_HOST'], // working
];
return $this->database;
}
}
and then
$test = new Constants();
print_r($test->useParentHost());
you have to declare some function to use $this, without/outside the function this will cause an error.
The variable $settings does not exist, perhaps you mean $this?
$this->constants['database']['APP_DB_HOST'];
Enjoy.

Categories