0

I've created a simple .ini file under projectRoot/conf/ with the below inside:

[db]
name="db_name"
usr="someone"
pass="a_definitely_secure_pass"
host="some_host"

If I call this in projectRoot/index.php like so:

$ini = parse_ini_file($_SERVER['DOCUMENT_ROOT']. '/conf/site.ini', true);
echo '<pre>'. print_r($ini,1) .'</pre>';

Then I get my array:

Array
(
    [db] => Array
        (
            [name] => db_name
            [usr] => someone
            [pass] => a_definitely_secure_pass
            [host] => some_host
        )
)

However, if I try to do this with classes, then I get a NULL output. Here is my base controller class:

<?php
    namespace App\Core;

    class Controller
    {
        protected $ini;

        public function __construct()
        {
            $this->ini = false;

            if (file_exists($_SERVER['DOCUMENT_ROOT']. '/conf/site.ini')) {
                $this->ini = parse_ini_file($_SERVER['DOCUMENT_ROOT']. '/conf/site.ini', true);
            }
        }
    }

Which I extend with a generic (minified) DB class:

<?php
    namespace App\Core;

    class Connection extends Controller
    {
        protected $conn;
        protected $qry;
        protected $stmt;

        public function __construct()
        {
            var_dump($this->ini); # this shows as NULL

            # this all fatal error's as it can't seem to parse the ini file correctly
            $this->conn = new \PDO(
                'mysql:host='. $this->ini['db']['host'] .';dbname='. $this->ini['db']['name'],
                $this->ini['db']['usr'],
                $this->ini['db']['pass']
            );

            $this->stmt = false;
            $this->qry = '';

            parent::__construct();
        }

        # etc

Which in turn, gets called on my index.php page for now (along with the test to parse the file):

<?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(-1);

    require_once $_SERVER['DOCUMENT_ROOT']. '/vendor/autoload.php';

    # this works
    $ini = parse_ini_file($_SERVER['DOCUMENT_ROOT']. '/conf/site.ini', true);
    echo '<pre>'. print_r($ini,1) .'</pre>';

    # trying to do it like this causes the fatal error
    $conn = new \App\Core\Connection();

    $conn->select(['*'], 'orders')
        ->join('order_items', 'order_id', 'orders', 'order_id', 1)
        ->where('total', 'lt')
        ->execute([5]);

    echo '<pre>'. print_r($conn->fetchAll(), 1) .'</pre>';

Which makes me think, maybe there's a scope issue here - but changing it from a protected var to public had no effect.

Why can't I set/get my .ini conf values using a class?

treyBake
  • 6,440
  • 6
  • 26
  • 57
  • Use the [global namespace](https://www.php.net/manual/en/language.namespaces.global.php) -> `$this->ini = \parse_ini_file($_SERVER['DOCUMENT_ROOT']. '/conf/site.ini', true);` – Raymond Nijland Oct 21 '19 at 15:20
  • @RaymondNijland same issue I'm afraid :/ plus, I thought global namespacing was for calling classes outside the current namespace? o.O – treyBake Oct 21 '19 at 15:21
  • i mean then within the `namespace App\Core;` class.. – Raymond Nijland Oct 21 '19 at 15:22
  • 1
    In your Connection class - would it help if you called `parent::__construct();` at the start of the constructor? – Nigel Ren Oct 21 '19 at 15:22
  • @RaymondNijland yeah that's where I did it^^ – treyBake Oct 21 '19 at 15:22
  • `file_exists` also needs to be `\file_exists` ... – Raymond Nijland Oct 21 '19 at 15:23
  • @NigelRen bingo that was it - bad `parent::__construct()` placement on my part – treyBake Oct 21 '19 at 15:23
  • @RaymondNijland I don't think the global namespace is used like that as much anymore - all works without the slashes, was a case of calling `parent::__construct()` first :S – treyBake Oct 21 '19 at 15:24
  • @NigelRen legend - literally about to ping asking for a dupe :p ty – treyBake Oct 21 '19 at 15:24
  • The dupe isn't exactly the issue, but it sort of covers it. – Nigel Ren Oct 21 '19 at 15:24
  • *"I don't think the global namespace is used like that as much anymore - all works without the slashes"* Uhm ok still the PHP manual says it important to use it like that even for PHP7,, Anyhow didn't you got notices/warnings ? – Raymond Nijland Oct 21 '19 at 15:25
  • @RaymondNijland weird, first time I've seen someone advocate it's usage (aside from returning to global namespacing within a namespace) - but may just be my experience thus far. I got a PDO fatal error but no other – treyBake Oct 21 '19 at 15:26
  • @NigelRen naah the second answer sums it up well - it's because the child __construct is effectively "overwriting" it's parent, you need to call the parent construct to get access to whatever goes on inside it - which I guess makes sense, I just chose to call it last instead of before I needed everything xD – treyBake Oct 21 '19 at 15:27
  • well the goal of those namespaces en global namespaces it to prevent name collisions using `\file_exists` and `\parse_ini_file` always makes sure it does not give a collision with a other namespace that also might have defined a custom file_exists or a parse_ini_file function in a class – Raymond Nijland Oct 21 '19 at 15:30
  • @RaymondNijland ahh from that perspective it makes sense - I'd hope that people wouldn't call their functions the same as native ones - but you can't stop people haha ty^ :) – treyBake Oct 21 '19 at 15:31
  • *" I'd hope that people wouldn't call their functions the same as native ones - but you can't stop people haha ty^ :) –"* i would call them fileExists() and parseIniFile() anyhow no you can't stop it indeed ... – Raymond Nijland Oct 21 '19 at 15:32

0 Answers0