简体   繁体   中英

Accessing a Global Variable in a Method

I think my question is kind of noobish but i can't figure out how this stuff is working with PHP. It is a autoloaded class and I want to use my logging class for it. I know I could have $log also as instance variable but I want it like that.

namespace Bal\Blub;

$log = new Logger('activities');
$log->pushHandler(new StreamHandler(__DIR__.'/../../log/activties.log', Logger::DEBUG));


$log->debug("is working here");

class Foo {
    public function bar() {
       global $log;
       $log->debug("this is my message");
    }
}

I don't understand why $log has no value in that case...

Edit: Of course I meant global and not public .

Ok so thanks for your code-style advises. I am quite aware that globals are bad practice. Though it was not my question. The answer for it is to use the global also in the namespace scope, which makes sense, but is a little strange if you are used to the PHP scripting approach.

namespace Bal\Blub;

global $log;

$log = new Logger('activities');
$log->pushHandler(new StreamHandler(__DIR__.'/../../log/activties.log', Logger::DEBUG));


$log->debug("is working here");

class Foo {
    public function bar() {
       global $log;
       $log->debug("this is my message");
    }
}

it is global $log. not public $log.

but be careful. globals are always evil. if you really need globals, use at least static variables.

<?php 
class Globalholder{
   public static $log;

}
Globalholder::$log = new Logger(...);


function foo(){
   $log = Globalholder::$log;
   $log->logsomething("Hello World");
}

global keyword, a static class property acting like a global variable, a singleton class...all can work, but since we're at it, why not trying to avoid bad practices and use DI?

Right now, your Foo class is tightly coupled with the Logger class, and that can make maintaince hard whenever, some day, you're going to change all the reference to the Logger class.

Why not something simpler like:

class Foo

   protected $logger;

   public function __construct(Logger $logger)
   {
      $this->logger = $logger;
   }

   public function bar($string)
   {
       $this->logger->debug($string);
   }
}

$log = new Logger('activities');
$foo = new Foo($log);
$foo->bar("test");

This way you're decoupling (I know this code can be made even better) the two classes, and you're also making the code easy testable by passing a mock Logger object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM