我开始将所有旧的mysql_函数转换为PDO并且在掌握这个概念时遇到一些麻烦。我希望能够在我的函数页面中访问我的PDO连接变量,以便可以根据需要调用它,而无需在每个函数的开头创建连接脚本。我会尝试尽可能地解释我的设置。
这是我的init.php页面,它加载了所有必需的php页面。此页面包含在我的每个页面的顶部,但不包含在功能页面中。
的init.php
<?php
session_start();
error_reporting(E_All);
require 'database/connect.php';
require 'functions/users.php';
require 'functions/general.php';
require 'functions/trainer.php';
?>
这是我的连接文件,用于打开我的数据库连接。是的我也打开了mysql_connect
,因为在将所有其他功能转换为PDO时,我无法禁用所有其他功能。
connect.php
<?php
$connect_error = 'Sorry there is a problem with the database connection.';
mysql_connect('Localhost', 'customn7', 'I<3deadlifts!') or die($connect_error);
mysql_select_db('customn7_cm') or die($connect_error) or die($connect_error);
?>
<?php
//PDO database connect
$config['db'] = array(
'host' => 'Localhost',
'username' => 'customn7',
'password' => '********',
'dbname' => 'customn7_cm'
);
try {
$db = new PDO('mysql:host=' .$config['db']['host']. ';dbname=' .$config['db']['dbname'], $config['db']['username'], $config['db']['password']);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->exec("SET CHARACTER SET utf8");
}
catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
?>
这是函数编写的functions/trainer.php
:
trainer.php
function exist_client_to_class($cd){
list($user_id, $class_id, $first_name, $last_name, $nickname) = explode('|', $cd);
try{
$stmt = $db->prepare('INSERT INTO clients
(`user_id`, class_id, first_name, last_name, nickname, date)
VALUES (:user_id, :class_id, :first_name, :last_name, :nickname, CURDATE())
');
$stmt->execute(array(
':user_id' => $user_id,
':class_id' => $class_id,
':first_name' => $first_name,
':last_name' => $last_name,
':nickname' => $nickname)
);
}
catch(PDOException $e) {
echo 'Error: ' . $e->getMessage();
}
}
截至目前,我无法从我的trainers.php页面访问我的$db
变量。有人可以帮我这个吗?
更新
以下是调用函数的代码:
// Post Selected name to current class.
if (isset($_POST['exist_to_class'])){
if (empty($_POST['client_data']) === true){
$errors [] = 'You much select a client to be added to the class.';
} else {
if (isset($_POST['client_data']) && !empty($_POST['client_data']));
foreach ($_POST['client_data'] as $cd){
exist_client_to_class($db, $cd);
header('Location: view_class.php?class_id='.$class_id.' ');
} // foreach $cd
} // else
} //isset
答案 0 :(得分:6)
首先,我强烈建议您不要听任何人告诉您将其设置为全球。
使用参数:
将连接对象传递给函数exist_client_to_class(PDO $pdo, $cd) { //...
这是所谓的依赖注入的简化版本。
更强大的版本包括将函数包装到类中(并从这些类中实例化对象),并将PDO对象(或某种Factory对象)传递给该对象的构造函数。然后它将在该对象的整个方法(函数)中“全局”可用。
答案 1 :(得分:6)
如果你能提供帮助,请不要使用全球。
当您使用init.php文件进行引导时,您可以依赖注入连接。
更改 connect.php
<?php
//PDO database connect
$config['db'] = array(
'host' => 'Localhost',
'username' => 'customn7',
'password' => '********',
'dbname' => 'customn7_cm'
);
try {
$db = new PDO('mysql:host=' .$config['db']['host']. ';dbname=' .$config['db']['dbname'], $config['db']['username'], $config['db']['password']);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->exec("SET CHARACTER SET utf8");
} catch(PDOException $e) {
echo 'Sorry there is a problem with the database connection :' . $e->getMessage();
}
<强> trainer.php 强>
class trainer_model{
function __construct(PDO $db){
$this->db = $db;
}
function exist_client_to_class($cd){
list($user_id, $class_id, $first_name, $last_name, $nickname) = explode('|', $cd);
try{
$stmt = $db->prepare('INSERT INTO clients
(`user_id`, class_id, first_name, last_name, nickname, date)
VALUES (:user_id, :class_id, :first_name, :last_name, :nickname, CURDATE())');
$stmt->execute(array(
':user_id' => $user_id,
':class_id' => $class_id,
':first_name' => $first_name,
':last_name' => $last_name,
':nickname' => $nickname)
);
}
catch(PDOException $e) {
echo 'Error: ' . $e->getMessage();
}
}
}
$trainer = new trainer_model($db);
//Then use as an object method
$trainer->exist_client_to_class($cd);
答案 2 :(得分:0)
你能不能使用inifile和一个带静态变量的函数吗? 像这样:
function pdo_connect() {
static $pdo;
$dsn="";
$opt="";`enter code here`
$charset = 'utf8';
if(!isset($pdo)) {
$config = parse_ini_file(_INIFILE_);
}
$dsn = "mysql:host=".$config['db_server'].";dbname=".$config['db_name'].";charset=".$charset;
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new PDO($dsn, $config['db_username'], $config['db_password'], $opt);
if($pdo === false) {
return "PDO connection ERROR:".PHP_EOL.";
}
return $pdo;
}//pdo
答案 3 :(得分:-3)
尝试创建一个全局文件php,您可以要求/包含所有需要数据库连接的文件....
然后在函数中使用全局$ db
function exist_client_to_class($ cd){
全球$ db;
}
答案 4 :(得分:-3)
您的trainers.php
脚本实际上可以访问$db
。例如,如果您将var_dump($db)
添加为trainers.php
的第一行,则会看到您可以访问它。
您遇到的问题是trainers.php
中的函数无法访问函数的SCOPE中的$db
。有几种方法可以解决这个问题。
最简单(也是最讨厌的IMO),就是添加一行
global $db;
作为每个函数的第一行WITHIN,您希望提供对全局范围内的$db
变量的访问。
另一种方法是简单地将DB对象作为参数传递给需要访问它的每个函数(依赖注入):
function exist_client_to_class($cd, $db){
// your function logic
}
并调用这样的函数:
exist_client_to_class($cd, $db);
如果你在PDO对象周围构建一个单独的类并从中获取PDO对象,那么最后(并且在我看来最好)的方法是这样做,只会创建一个实例。这可能看起来像这样
class db {
protected static $pdo_instance = NULL;
protected static $dsn = 'mysql:dbname=somedb;host=127.0.0.1'; // your DSN
protected static $user = 'username';
protected static $password = 'password';
protected function __construct() {
try {
self::$pdo_instance = new PDO (self::$dsn, self::$user, self::$password);
} catch (PDOException $e) {
return 'PDO Connection failed: ' . $e->getMessage();
}
return true;
}
public static function get_pdo_instance() {
if (isset(self::$pdo_instance) && self::$pdo_instance instanceof PDO) {
return self::$pdo_instance;
} else {
$result = self::__construct();
if (true === $result) {
return self::$pdo_instance;
} else {
throw new Exception($result); // or however you want to handle the connection error
}
}
}
要访问,而不是在任何地方使用$db
,只需执行
$db = db::get_pdo_instance();
在你的职能范围内。
或者你甚至可以直接致电lile
$stmt = db::get_PDO_instance()->prepare('YOUR SQL HERE');
您甚至可以考虑单独和依赖注入的混合:
function exist_client_to_class($cd, $db){
// your function logic
}
exist_client_to_class($cd, db::get_PDO_instance());
答案 5 :(得分:-4)
创建单例数据库类:
class Database
{
protected static $instance=false;
public static function getInstance()
{
if(self::$instance===false) self::$instance=new Database();
return $instance;
}
protected function __construct()
{
//Connect here
}
//Whatever other functions you need
}
使用它:
$db=Database::getInstance();
$connection=$db->getConnection();...