Let me start by explaining. I have a few global database connections and have a few simple functions that use each one and perform queries and such.
Because i want to use the connections 开发者_运维问答more then once, and to save me defining them each time in each function i have created them as globals at the top of the document. However i am just wondering that instead of having to write
global $mysql_db1, $mysql_db2, $mysql_db3, $mysql_db4, $mysql_db5;
Is there anyway to make this happen without me having to copy and paste it each time?
I know its trivial but i just wanted to speed up my own development,
I'd create a class ConnectionManager which stores these connections and use an instance of the class for any function using the db :)
Using a Singleton is also a good idea if you don't want to put the parameter each time.
Your best bet is to declare them in an object-oriented way, say as properties of a Singleton, and then access them that way. If you are insistent on doing things in a way which will make subsequent developers sad, you can use the $GLOBALS
array. Globals are just a bad idea, and I wish that the keyword could be struck from the language, frankly.
A very simple version of something you could use:
class ConnectionHolder
{
public $mysql_db1;
private static $inst;
public static &getInstance()
{
if( !self::$inst )
self::$inst = new ConnectionHolder();
return self::$inst;
}
private function __construct()
{
$this->mysql_db1 = // ... you may want another nameing convension.
// yada yada
}
}
Then, in your functions:
$ch =& ConnectionHolder::getInstance()
$ch->mysql_db1;
Globals are usually regarded as bad practice. I won't pontificate at you about it, but check out this article: http://blog.case.edu/gps10/2006/07/22/why_global_variables_in_php_is_bad_programming_practice
You can use the $GLOBALS
superglobal to access any variable that has been defined in the global scope (docs). Thus, in your example code, simply using $GLOBALS['mysql_db1']
would be the equivalent of having the line global $mysql_db1;
and then using $mysql_db1
.
I cannot stress enough (without pontificating) how bad of a plan this is. YOU might be all right with it the entire time you're developing, but poor poor Johnny Nextguy, and may the Gods of Code save you if you include a third-party script that also uses globals... and there's a conflict of variable names. Now you're in for it!
As has been suggested, you are better off encapsulating your database functionality in a class. If you use a static class, you still have all the benefits of a global variable without a polluted scope or danger of overwriting.
Here is a sample database class, along with usage:
// put this in a library file or some place that all scripts include
require_once('database_class.php');
$db = new db(array(
'host'=>'localhost'
'user'=>'db_user_name'
'password'=>'db_password',
'database_name'=>'my_database'
));
// now anywhere in code you want to use it
$array = db::getRows('SELECT id, name FROM users');
$field = db::getField('SELECT name FROM users WHERE id=10');
<?php
// database_class.php
class db {
static protected $resource_link = null;
function __construct($args=false) {
if ($args===false || !is_array($args))
return false;
if (
!isset($args['host']) ||
!isset($args['user']) ||
!isset($args['password']) ||
!isset($args['database_name'])
)
return critical_error('Missing database configuration data.');
self::$resource_link = @mysql_connect($args['host'],$args['user'],$args['password']);
if (!self::$resource_link)
return critical_error('Error connecting to database 2001. MySQL said:<br>'.mysql_error());
@mysql_select_db($args['database_name'], self::$resource_link);
return;
}
// return a single-dimmension array of fields as string
static public function getFields ($sql=false, $field=false) {
$res = null;
if ($sql!==false) {
$query_obj = mysql_query($sql, self::$resource_link);
if ($query_obj) {
$res = array();
while ($this_row = mysql_fetch_array($query_obj)) {
if ($field !== false && isset($this_row[$field]))
$res[] = $this_row[$field];
else
$res[] = $this_row[0];
}
} // end :: if query object is not null
} // end :: if $sql is not false
return $res;
}
// return a single-dimmension array of fields as string with keyfield as key
static public function getKeyFields ($sql=false, $key_field='id', $list_field='id') {
$res = null;
if ($sql!==false) {
$query_obj = mysql_query($sql, self::$resource_link);
if ($query_obj) {
while ($this_row = mysql_fetch_array($query_obj)) {
if (isset($this_row[$key_field]))
$res[$this_row[$key_field]] = $this_row[$list_field];
}
} // end :: if query object is not null
} // end :: if $sql is not false
return $res;
}
// return a single field as string from the first row of results
static public function getField ($sql=false) {
$res = null;
if ($sql!==false) {
$query_obj = mysql_query($sql, self::$resource_link);
if ($query_obj) {
$this_array = mysql_fetch_array($query_obj);
if (is_array($this_array))
return $this_array[0];
} // end :: if query object is not null
} // end :: if $sql is not false
return $res;
}
// return a single row as an array
static public function getRow ($sql=false) {
$res = null;
if ($sql!==false) {
$query_obj = mysql_query($sql, self::$resource_link);
if ($query_obj)
$res = mysql_fetch_assoc($query_obj);
} // end :: if $sql is not false
return $res;
}
// return an array of rows as arrays of strings
static public function getRows ($sql=false) {
$res = null;
if ($sql!==false) {
$query_obj = mysql_query($sql, self::$resource_link);
$res = array();
if ($query_obj) {
while ($this_row = mysql_fetch_assoc($query_obj)) {
$res[] = $this_row;
}
} // end :: if query object is not null
} // end :: if $sql is not false
return $res;
}
// return an array of rows as arrays of strings, using specified field as main array keys
static public function getKeyRows ($sql=false, $key_field='id', $include_key_in_results=true) {
$res = null;
if ($sql!==false) {
$query_obj = mysql_query($sql, self::$resource_link);
if ($query_obj) {
$res = array();
while ($this_row = mysql_fetch_assoc($query_obj)) {
if (isset($this_row[$key_field])) {
$res[$this_row[$key_field]] = $this_row;
if ($include_key_in_results == false)
unset($res[$this_row[$key_field]][$key_field]);
} // end :: if checking for key field in result array
} // end :: while looping query obj
} // end :: if query object is not null
} // end :: if $sql is not false
return $res;
}
// do an update query, return true if no error occurs
static public function update ($sql=false) {
$res = false;
if ($sql!==false) {
$query_obj = mysql_query($sql, self::$resource_link);
if ($query_obj && strlen(mysql_error()) < 1)
$res = true;
}
return $res;
}
// do an insert query, return the auto increment ID (if there is one)
static public function insert ($sql=false) {
$res = null;
if ($sql !== false) {
$query_obj = mysql_query($sql, self::$resource_link);
if ($query_obj)
$res = mysql_insert_id(self::$resource_link);
}
return $res;
}
}
?>
In direct answer to your question: no.
A practical answer to your question points out that globals are not such a hot idea. Be aware that most of the arguments out there I believe are invalid and revolve around others saying "ewww, that's gross!" or "you'll unleash the devil!".
However, they all sort of dance around this one issue: if two parts of your program try to use the same global variable $foo
for different purposes (ie, accidentally they decided on the same name) then there is no guarantee an error will occur. This is why it is recommended to use a different storage method, such as a class, because two classes named Foo
will definitely cause an error.
In context of your program, one would probably recommend creating a ConnectionManager
singleton, where you could grab database connections by writing something like $conn1 = ConnectionManager::getConnection('conn1');
.
精彩评论