Welcome Guest, Not a member yet? Register   Sign In
Config Static Variables Not Working
#11

(08-04-2021, 02:41 AM)paulbalandan Wrote: I think I have a guess on the problem but needs some confirmation.
Can you share the code of your My_config?

Class objects are saved by reference by default so changing one should affect the other. I just need to confirm the structure of your config class to know the culprit behind this.

Here is sample code for your illustration, just ignore there is user array in my question:

PHP Code:
namespace Config;
use 
CodeIgniter\Config\BaseConfig;

class 
My_config extends BaseConfig {

   public static $user '';

   public static function load_values() {

      self::$user "Any User Name";

   }



Reply
#12

(This post was last modified: 08-04-2021, 07:20 AM by paulbalandan.)

Thanks. I think I know now.

1. You are not defining the $config in your BaseController. This means you are dynamically creating the property. Why is this a problem? First, when you call $this->config on BaseController you are basically creating it on the fly on that class. However, when you call $this->config on Admin the config is created anew because it is not there to begin with.

So you need to define the config explicitly.
PHP Code:
class BaseController
{
    
/**
     * Need to define this explicitly in the base class so that
     * extending classes have access to this. If not, each
     * child class would have their own versions of this.
     */
    
public $config;

    ...


2. Next, it seems you are only using static properties and methods in your config. Since these static members belong to the class, you can skip instantiating it using config(). Instead, you can directly invoke the statics from the class itself.
PHP Code:
# instead of calling like this
$this->config config('My_config');

# you can do this
# you do not need this again in admin, just in base is ok
$this->config = \Config\My_config::class;

# then initialize it
$this->config::load_values();

# now base and admin can access static props
echo $this->config::$user

proof that this works
https://3v4l.org/cXDLX

For #2 please note that the ::class notation should only be used as solution if strictly all properties and methods are static. If there's at least one that is not, you should use the config function
Reply
#13

(This post was last modified: 08-04-2021, 09:34 AM by myo.)

(08-04-2021, 07:18 AM)paulbalandan Wrote: Thanks. I think I know now.

1. You are not defining the $config in your BaseController. This means you are dynamically creating the property. Why is this a problem? First, when you call $this->config on BaseController you are basically creating it on the fly on that class. However, when you call $this->config on Admin the config is created anew because it is not there to begin with.

So you need to define the config explicitly.
PHP Code:
class BaseController
{
    /**
    * Need to define this explicitly in the base class so that
    * extending classes have access to this. If not, each
    * child class would have their own versions of this.
    */
    public $config;

    ...


2. Next, it seems you are only using static properties and methods in your config. Since these static members belong to the class, you can skip instantiating it using config(). Instead, you can directly invoke the statics from the class itself.
PHP Code:
# instead of calling like this
$this->config config('My_config');

# you can do this
# you do not need this again in admin, just in base is ok
$this->config = \Config\My_config::class;

# then initialize it
$this->config::load_values();

# now base and admin can access static props
echo $this->config::$user

proof that this works
https://3v4l.org/cXDLX

For #2 please note that the ::class notation should only be used as solution if strictly all properties and methods are static. If there's at least one that is not, you should use the config function

No, it did not resolve my issue. I have mixed methods in config file so can't use ::class. 
Following is simplified version of the problem. You can check it here: https://3v4l.org/9G2Ab and also try it in Codeigniter. 
I think  "function initController()" in "BaseController" is not executed like " function __construct()" automatically when its extended by another class as my all code in BaseController is inside "function initController()". Am I right? 
If you can make following code print "100" in AdminController in Codeigniter then my issue is resolved.

PHP Code:
<?php
 
 
class BaseController {
 
 public static 
$var_test '#';
 
   public function __construct() {
     self::$var_test "100";
   }
 }
 
 
 class 
AdminController extends BaseController {
 
    public function render() {
 
         echo parent::$var_test// Prints 100 here (www.3v4l.org/9G2Ab) which is correct
                                 // Prints # in CI 4 AdminController extended from BaseController which is wrong 
   }
 }
 
 
$adm = new AdminController;
 
var_dump($adm->render());
?>
Reply
#14

If you have your own initController() method in AdminController, then you need to call the parent initController first.
PHP Code:
class AdminController extends BaseController
{
    ...

    public function 
initController(RequestInterface $requestResponseInterface $responseLoggerInterface $logger)
    {
        
parent::initController(); // initializes all code in BaseController
        
echo self::$var_test;
    }

Reply
#15

(08-04-2021, 07:20 PM)paulbalandan Wrote: If you have your own initController() method in AdminController, then you need to call the parent initController first.
PHP Code:
class AdminController extends BaseController
{
    ...

    public function initController(RequestInterface $requestResponseInterface $responseLoggerInterface $logger)
    {
        parent::initController(); // initializes all code in BaseController
        echo self::$var_test;
    }

Thankyou for your time but we need to call initController() with required arguments. I have found a work around, I have created a separate method in BaseController & can call it whenever needed. But its a new learning for me that BaseController initController is called only after child controller constructor.
Reply
#16

I really do not like static access from object instances, it always gets confusing (as is the case here). My advice would be to keep using the Config as you are for the object properties, but anytime you need to access the static properties just do it from the class directly:

use Config\My_config

echo My_config::$users_array[0];
Reply
#17

(08-06-2021, 04:56 AM)MGatner Wrote: I really do not like static access from object instances, it always gets confusing (as is the case here). My advice would be to keep using the Config as you are for the object properties, but anytime you need to access the static properties just do it from the class directly:

use Config\My_config

echo My_config::$users_array[0];

I also don't like to use statics usually but in this case I am loading a couple of json files & don't wanna load again & again to avoid overhead. So the only solution is to use static variables as they maintain the state. 
While I was resolving this issue I discovered a very strange thing that some files are loaded again & again. I posted this question here https://forum.codeigniter.com/thread-79853.html.
Reply
#18

Just to be clear: I have no problem with static properties and I use them quite frequently myself. I personally wouldn’t use them on a Config, since the shared instance is already ensuring your file is only loaded once, but that’s up to you.

What I meant was I don’t like *accessing static properties from an instance*. Notice the difference with this from my example above:

$config = config('My_config');
// intermediate code here
echo $config::$users_array[0];

This is allowed in PHP but it adds a layer of uncertainty because it isn’t apparent which class you are accessing. My example above explicitly references the class so you’re certain. Instance access adds nothing except guaranteeing hat your constructor has been run, but there are already better ways to verify the static properties have been filled (like a static accessor method to private properties).
Reply




Theme © iAndrew 2016 - Forum software by © MyBB