Initializing a controller that uses Selenium I've outsourced the setup functions from my class to another file, I outsourced initDriver from the class PortalController to the class SeleniumUtility.

Before:

class PortalController extends Controller
{       
    protected $driver = NULL;

    const URL_GOOGLE = 'https://www.google.com';
    const SELENIUM_SERVER_ADDRESS = 'http://localhost:4444/wd/hub';
    const DRIVER_TIMEOUT = 5000;

    /**
    *   Initialize Driver
    * As you can see I am using `initDriver` to initialize the protected property `$driver`.
    */
    public function initDriver()
    {
        if ($this-&gt;driver === NULL) {

            $this-&gt;driver = RemoteWebDriver::create(self::SELENIUM_SERVER_ADDRESS, DesiredCapabilities::firefox(), self::DRIVER_TIMEOUT);
        }
    }

    public function main()
    {
        $this-&gt;initDriver();

        //start firefox and open google
        $this-&gt;driver-&gt;get(self::URL_GOOGLE);
    }

...

}


After:



PortalController

use App\Http\Utility\SeleniumUtility As Selenium;

class PortalController extends Controller
{       
    protected $driver = NULL;

    const URL_GOOGLE = 'https://www.google.com';

    public function main()
    {
        if ($this-&gt;driver === NULL) {
            $this-&gt;driver = Selenium::initDriver(array($this, "driver"));
        }

        //start firefox and open google
        $this-&gt;driver-&gt;get(self::URL_GOOGLE);
    }
...

}


SeleniumUtility

class SeleniumUtility
{
    const SELENIUM_SERVER_ADDRESS = 'http://localhost:4444/wd/hub';
    const DRIVER_TIMEOUT = 5000;

    /**
    *   Initialize Driver
    *   @return RemoteWebDriver
    */
    public static function initDriver($thisObj)
    {    
        return RemoteWebDriver::create(self::SELENIUM_SERVER_ADDRESS, DesiredCapabilities::firefox(), self::DRIVER_TIMEOUT);
    }
...
}


But I am not sure if this is the right way, it feels dirty.
I also now have to do the check if ($this-&gt;driver === NULL) { in PortalController, If i do the check in initDriver then I get:

Call to a member function get() on null on the line where I try to open the browser with google $this-&gt;driver-&gt;get(self::URL_GOOGLE);

I appreciate any feedback on how to improve this if it is possible.
I found two better alternatives.

1. Change $driver from protected to public

Then you can pass the $this object directly to initDriver:

PortalController

public $driver = null;  

public function main()
{
    //Before: $this-&gt;driver = Selenium::initDriver(array($this, "driver"));

    //After:
    Selenium::initDriver($this);
    ...
}


SeleniumUtility

public static function initDriver($thisObj)
{    
    //Now I can do the if null check here

    if (thisObj-&gt;driver === NULL) {
       $thisObj-&gt;driver = RemoteWebDriver::create(self::SELENIUM_SERVER_ADDRESS, DesiredCapabilities::firefox(), self::DRIVER_TIMEOUT);
    }
}




2. Use getter and setter

PortalController

protected $driver = null;  

public function getDriver()
{
    return $this-&gt;driver;
}

public function setDriver($driver)
{
    $this-&gt;driver = $driver;
}

public function main()
{
    //Before: $this-&gt;driver = Selenium::initDriver(array($this, "driver"));

    //After:
    Selenium::initDriver($this);
    ...
}


SeleniumUtility

public static function initDriver($thisObj)
{    
    //Now I can do the if null check here

    if (thisObj-&gt;getDriver() === NULL) {
        $thisObj-&gt;setDriver( RemoteWebDriver::create(self::SELENIUM_SERVER_ADDRESS, DesiredCapabilities::firefox(), self::DRIVER_TIMEOUT));
    }
}


But in my opinion it makes no sense to make the driver protected, so the first solution is faster and better. As long as we do not store any valuable information like passwords in the driver, keeping it public is perfectly OK.