3

私はすべての古いmysql_関数をPDOに変換し始めており、この概念を理解するのに少し問題があります。各関数の先頭に接続スクリプトを作成せずに必要に応じて呼び出すことができるように、関数ページ全体でPDO接続変数にアクセスできるようにしたいと考えています。私は自分のセットアップを可能な限り説明しようとします。

これは、必要なすべてのphpページをロードする私のinit.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';
?>

これが私のdb接続を開く接続ファイルです。はい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();
}

}

$db現在のところ、trainers.phpページから変数にアクセスできません。誰かがこれを手伝ってくれますか?

アップデート

関数を呼び出すコードは次のとおりです。

// 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
4

6 に答える 6

6

まず、グローバルに設定するように言われる人の言うことを聞かないことを強くお勧めします。


引数を使用して、接続オブジェクトを関数に渡します。

exist_client_to_class(PDO $pdo, $cd) { //...

これは、依存性注入と呼ばれるものの簡略化されたバージョンです。

より堅牢なバージョンには、関数をクラスにラップし(およびそれらのクラスからオブジェクトをインスタンス化し)、PDOオブジェクト(またはある種のFactoryオブジェクト)をそのオブジェクトのコンストラクターに渡すことが含まれます。そうすれば、そのオブジェクトのメソッド(関数)全体で「グローバルに」利用できるようになります。

于 2012-11-19T21:43:22.693 に答える
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);
于 2012-11-19T21:45:22.963 に答える
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
于 2016-08-02T15:36:17.627 に答える
-3

データベース接続を必要とするすべてのファイルに要求/含めることができるグローバルファイルphpを作成してみてください。

次に、関数内でグローバル$dbを使用します

関数exist_client_to_class($ cd){

グローバル$db;

}

于 2012-11-19T21:35:27.143 に答える
-3

スクリプトtrainers.phpは実際にはにアクセスできます$db。たとえばvar_dump($db)、の最初の行として追加した場合trainers.phpは、それにアクセスできることがわかります。

あなたが抱えている問題は、内の関数が関数のスコープ内にtrainers.phpアクセスできないことです。$dbこれを処理する方法は本当にいくつかあります。

最も単純な(そして最もハックなIMO)は、行を追加することです

global $db;

各関数内の最初の行として、$dbグローバルスコープにある変数へのアクセスを提供します。

もう1つの方法は、次のように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());
于 2012-11-19T21:59:44.273 に答える
-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();...
于 2012-11-19T21:41:29.887 に答える