복붙노트

PDO 연결을 올바르게 설정하는 방법

PHP

PDO 연결을 올바르게 설정하는 방법

때때로 데이터베이스에 연결하는 것과 관련된 질문을 봅니다. 대부분의 해답은 내가하는 방식이 아니거나 올바르게 대답하지 못할 수도 있습니다. 어쨌든; 내가 그것을하는 방식이 나를 위해 일하기 때문에 나는 그것에 관해 결코 생각하지 않고 있었다.

그러나 여기 미친 생각이 있습니다. 어쩌면 나는이 모든 일을 잘못하고있다. PHP와 PDO를 사용하여 MySQL 데이터베이스에 올바르게 연결하고 쉽게 액세스 할 수있는 방법을 알고 싶습니다.

방법은 다음과 같습니다.

우선, 내 파일 구조가 아래에 있습니다.

public_html/

* index.php  

* initialize/  
  -- load.initialize.php  
  -- configure.php  
  -- sessions.php   

index.php 맨 위에는 require ( 'initialize / load.initialize.php');가 있습니다.

load.initialize.php

#   site configurations
    require('configure.php');
#   connect to database
    require('root/somewhere/connect.php');  //  this file is placed outside of public_html for better security.
#   include classes
    foreach (glob('assets/classes/*.class.php') as $class_filename){
        include($class_filename);
    }
#   include functions
    foreach (glob('assets/functions/*.func.php') as $func_filename){
        include($func_filename);
    }
#   handle sessions
    require('sessions.php');

클래스를 포함하는 것이 더 낫거나 더 정확한 방법이 있다는 것을 알고 있지만 그것이 무엇인지 기억할 수는 없습니다. 아직 보지 못했지만 자동로드가있는 것 같아요. 그런 것 ...

configure.php 여기에서는 기본적으로 일부 php.ini 속성을 무시하고 사이트의 다른 전역 구성을 수행합니다.

connect.php 다른 클래스가이 클래스를 확장 할 수 있도록 클래스에 연결을 넣었습니다 ...

class connect_pdo
{
    protected $dbh;

    public function __construct()
    {
        try {
            $db_host = '  ';  //  hostname
            $db_name = '  ';  //  databasename
            $db_user = '  ';  //  username
            $user_pw = '  ';  //  password

            $con = new PDO('mysql:host='.$db_host.'; dbname='.$db_name, $db_user, $user_pw);  
            $con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
            $con->exec("SET CHARACTER SET utf8");  //  return all sql requests as UTF-8  
        }
        catch (PDOException $err) {  
            echo "harmless error message if the connection fails";
            $err->getMessage() . "<br/>";
            file_put_contents('PDOErrors.txt',$err, FILE_APPEND);  // write some details to an error-log outside public_html  
            die();  //  terminate connection
        }
    }

    public function dbh()
    {
        return $this->dbh;
    }
}
#   put database handler into a var for easier access
    $con = new connect_pdo();
    $con = $con->dbh();
//

최근에 나는 OOP를 배우기 시작했고 mysql 대신 PDO를 사용하기 시작했기 때문에 방대한 개선의 여지가 있다고 생각합니다. 그래서 방금 초보자 용 자습서 2 개를 읽고 다른 것들을 시도했습니다 ...

sessions.php 정규 세션을 처리하는 것 외에도 다음과 같은 세션으로 일부 클래스를 초기화합니다.

if (!isset($_SESSION['sqlQuery'])){
    session_start();
    $_SESSION['sqlQuery'] = new sqlQuery();
}

이 방법으로이 클래스를 사용할 수 있습니다. 이것은 좋은 습관이 아닐 수도 있습니다 (?) ... 어쨌든,이 접근법은 내가 어디에서나 할 수있게 해줍니다 :

echo $_SESSION['sqlQuery']->getAreaName('county',9);  // outputs: Aust-Agder (the county name with that id in the database)

내 connect_pdo 클래스를 확장하는 내 sqlQuery 클래스 안에는 데이터베이스에 대한 요청을 처리하는 getAreaName이라는 공용 함수가 있습니다. 꽤 산뜻한 것 같아요.

매력처럼 작동합니다. 그래서 그것이 기본적으로 제가하는 방법입니다. 또한, 내 수업에서 내 DB에서 무언가를 가져올 필요가있을 때마다, 나는 이것과 비슷한 것을합니다 :

$id = 123;

$sql = 'SELECT whatever FROM MyTable WHERE id = :id';
$qry = $con->prepare($sql);
$qry -> bindParam(':id', $id, PDO::PARAM_INT);
$qry -> execute();
$get = $qry->fetch(PDO::FETCH_ASSOC);

connect_pdo.php 내부의 변수에 연결을 설정 했으므로이 변수를 참조해야만합니다. 그것은 작동합니다. 예상 한 결과가 나옵니다 ...

그러나 그것과 상관없이; 만약 내가 여기서 벗어나면 나 한테 말해 줄 수 있다면 정말 고마워. 대신 내가해야 할 일, 개선 할 수있는 부분 또는 변경할 수있는 부분 ...

나는 배우려고 열심이다 ...

해결법

  1. ==============================

    1.

    내가 본 것처럼이 경우의 목표는 두 가지입니다.

    PDO 연결을 처리하기 위해 익명 함수와 팩토리 패턴을 모두 사용하는 것이 좋습니다. 그 사용법은 다음과 같습니다.

    $provider = function()
    {
        $instance = new PDO('mysql:......;charset=utf8', 'username', 'password');
        $instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
        return $instance;
    };
    
    $factory = new StructureFactory( $provider );
    

    그런 다음 동일한 파일의 다른 파일 또는 하위 파일 :

    $something = $factory->create('Something');
    $foobar = $factory->create('Foobar');
    

    공장 자체는 다음과 같이 보일 것입니다 :

    class StructureFactory
    {
        protected $provider = null;
        protected $connection = null;
    
        public function __construct( callable $provider )
        {
            $this->provider = $provider;
        }
    
        public function create( $name)
        {
            if ( $this->connection === null )
            {
                $this->connection = call_user_func( $this->provider );
            }
            return new $name( $this->connection );
        }
    
    }
    

    이 방법을 사용하면 필요할 때만 연결이 생성되도록하는 중앙 집중식 구조를 가질 수 있습니다. 또한 단위 테스트 및 유지 보수 프로세스를 훨씬 쉽게 만들어줍니다.

    이 경우 공급자는 부트 스트랩 단계에서 찾을 수 있습니다. 이 접근법은 또한 DB에 연결하는 데 사용하는 구성을 정의 할 수있는 명확한 위치를 제공합니다.

    이것은 매우 단순화 된 예입니다. 또한 다음과 같은 두 개의 비디오를 보는 것이 좋습니다.

    또한, PDO 사용에 관한 적절한 자습서 (온라인에서 잘못된 자습서 로그가 있음)를 읽는 것이 좋습니다.

  2. ==============================

    2.

    DB 연결에 전역으로 액세스하기 위해 $ _SESSION을 사용하지 말 것을 제안합니다.

    몇 가지 중 하나를 수행 할 수 있습니다 (최악의 사례부터 최우수 사례까지).

    나는 마지막 것을 매우 추천 할 것이다. DI (Dependency Injection), IoC (Inversion of Control) 또는 단순히 할리우드 원리 (우리에게 전화하지 마십시오, 우리는 당신에게 전화 할 것입니다)로 알려져 있습니다.

    그러나 프레임 워크가 없으면 조금 더 고급화되고 더 많은 "배선"이 필요합니다. 따라서 의존성 주입이 너무 복잡하다면 전역 변수가 아니라 싱글 톤 레지스트리를 사용하십시오.

  3. ==============================

    3.

    나는 최근에 나 자신과 비슷한 대답 / 질문을했다. 누군가가 관심을 가지기 때문에 내가 한 일입니다.

    <?php
    namespace Library;
    
    // Wrapper for \PDO. It only creates the rather expensive instance when needed.
    // Use it exactly as you'd use the normal PDO object, except for the creation.
    // In that case simply do "new \Library\PDO($args);" with the normal args
    class PDO
      {
      // The actual instance of PDO
      private $db;
    
      public function __construct() {
        $this->args = func_get_args();
        }
    
      public function __call($method, $args)
        {
        if (empty($this->db))
          {
          $Ref = new \ReflectionClass('\PDO');
          $this->db = $Ref->newInstanceArgs($this->args);
          }
    
        return call_user_func_array(array($this->db, $method), $args);
        }
      }
    

    이 라인을 수정하기 만하면됩니다 :

    $DB = new \Library\PDO(/* normal arguments */);
    

    타입 힌트는 (\ Library \ PDO $ DB)에 사용합니다.

    그것은 받아 들인 대답과 너의 것 둘 다에 진짜 유사하다; 그러나 그것은 특히 장점이 있습니다. 다음 코드를 고려하십시오.

    $DB = new \Library\PDO( /* args */ );
    
    $STH = $DB->prepare("SELECT * FROM users WHERE user = ?");
    $STH->execute(array(25));
    $User = $STH->fetch();
    

    보통 PDO처럼 보일 수도 있지만 (\ Library \에 의해서만 바뀝니다), 첫 번째 메소드를 호출 할 때까지 객체를 초기화하지 않습니다. 따라서 PDO 객체 생성이 약간 비싸므로 최적화가 이루어집니다. 투명한 클래스이거나 게으름로드의 한 형태 인 고스트 (Ghost)입니다. $ DB를 일반적인 PDO 인스턴스로 처리하고, 전달하고, 동일한 작업을 수행 할 수 있습니다.

  4. ==============================

    4.

    $dsn = 'mysql:host=your_host_name;dbname=your_db_name_here'; // define host name and database name
        $username = 'you'; // define the username
        $pwd='your_password'; // password
        try {
            $db = new PDO($dsn, $username, $pwd);
        }
        catch (PDOException $e) {
            $error_message = $e->getMessage();
            echo "this is displayed because an error was found";
            exit();
    }
    

    또는 http://ask.hcig.co.za/?p=179에서 읽으십시오.

  5. from https://stackoverflow.com/questions/11369360/how-to-properly-set-up-a-pdo-connection by cc-by-sa and MIT lisence