tags:

views:

129

answers:

5

I have a small problem - I want to decrease code duplication in my site, and the best way that I can see of doing that is to remove a lot of unnecessary instances of variable setting.

One of the most common is the $baseUrl variable, which contains the http host and php self values, for convenience. However, I have to set it for each function:

class Site
{
function outputPage()
{    
$baseUrl = "http://". $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
}
}

This is then typically included in any links that the site uses:

echo '<a href="' . $baseUrl .'/article/jun/example11/">Example 11</a>';

It's set around six times throughout the class, once per function that needs it - is there any way to set it once and then allow all the functions to access it?

A: 

I think you should use a constant for it:

define("BASE_URL", "http://".$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER['PHP_SELF']), '/\\'));

Then use

echo '<a href="' . BASE_URL .'/article/jun/example11/">Example 11</a>';

It is appropriate to use a constant because the value never changes in the run time of the script. You could also set a class variable for it. Which still will have to be duplicated in every class.

class myClass{
    private $baseURL;
    function __construct()
    {
        $this->baseURL = http://".$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
    }
    function speak()
    {
        echo $this->baseURL;
    }
}
Chacha102
+5  A: 

Methods of a class can access members of that class.

class Site {

  private $baseurl;

  public function __construct()
  {
    $this->baseurl = "http://www.somesite.com";
  }

  public function hello()
  {
    print "My baseurl is " . $this->baseurl;
  }

}

$site = new Site;
$site->hello(); // My baseurl is http://www.somesite.com
Jonathan Sampson
He can't use concatenations or variables outside of methods.
Chacha102
What? Where did he say he can't use concat or variables?
Jonathan Sampson
No. He doesn't need to concat. There are many ways to build a string without using .
Jonathan Sampson
For your example to apply to his set up, he would have to use variables and concat in place of your somesite.com variable, and concating outside of a method is illegal.
Chacha102
$foo = "Hello {$bar}"; doesn't use concat...
Jonathan Sampson
The value of `private $baseurl` must be static. Per documentation : http://us.php.net/manual/en/language.oop5.basic.php
Chacha102
A: 

I prefer to define those sorts of things as class constants.

class Settings
{
    const BASE_URL = "http://google.com";
}

Then you can use require_once("settings.php"); anywhere and have access to Settings::Base_URL

Sean Clark Hess
Oh, looks like you need some computation. You can declare it as a variable instead of a const `public BASE_URL` and then compute it at the top of the file
Sean Clark Hess
+4  A: 

You could set it as a class variable, and initialize it in the constructor :

class Site {
    public function __construct() {
        $this->baseUrl = "http://". $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
        var_dump('constructor : ' . $this->baseUrl);
    }
    function outputPage() {    
        // use $this->baseUrl
        var_dump($this->baseUrl);
    }
    protected $baseUrl;
}

And, then, when using the class :

$a = new Site();
$a->outputPage();

You'll get :

string 'constructor : http://tests/temp' (length=31)
string 'http://tests/temp' (length=17)


In some cases, you could also initialize "on the fly" when you're declaring it (on the line with protected, in my example).
But this doesn't work with everything ; you can't call a function there, for instance, if I remember correctly ; you can't concatenate strings either :

class Site {
    function outputPage() {    
        // use $this->baseUrl
        var_dump($this->baseUrl);
    }
    protected $baseUrl = "http://". $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
}

Would give you this error :

Parse error: syntax error, unexpected '.', expecting ',' or ';'

But this :

class Site {
    function outputPage() {    
        // use $this->baseUrl
        var_dump($this->baseUrl);
    }
    protected $baseUrl = "http://www.google.com";
}

Would work -- but it's not as powerful, and you can't really do whatever you might want, this way...

Pascal MARTIN
Works for me. Thank you!
different
You're welcome :-) Have fun!
Pascal MARTIN
+1  A: 

just create a class member with that variable :)

class Site {
  private $baseurl;
  public function __construct() {
    $this->baseurl = "http://". $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
  }
  public function outputPage() {    
    echo $this->baseurl;
  }
}
knittl
This will get a "Parse error: syntax error, unexpected '.', expecting ',' or ';'" : you cannont concatenate strings outside of a method.
Pascal MARTIN
You can't use variables or functions as well.
Chacha102
good catch, i was too fast writing my answer. fixed using a constructor
knittl