কীভাবে সঠিকভাবে পিডিও সংযোগ স্থাপন করবেন


92

সময়ে সময়ে আমি ডাটাবেসে সংযোগ সম্পর্কিত প্রশ্নগুলি দেখতে পাচ্ছি।
বেশিরভাগ উত্তরগুলি আমি যেভাবে করি তা নয় বা আমি উত্তরগুলি সঠিকভাবে নাও পেতে পারি। যাইহোক; আমি কখনই এ নিয়ে ভাবিনি কারণ আমি যেভাবে এটি করি তা আমার পক্ষে কার্যকর।

তবে এখানে একটি ক্রেজি চিন্তাভাবনা; হয়তো আমি এই সব ভুল করছি, এবং যদি এটি হয়; আমি কীভাবে পিএইচপি এবং পিডিও ব্যবহার করে কোনও মাইএসকিউএল ডাটাবেসে সঠিকভাবে সংযোগ স্থাপন করব এবং এটি সহজেই অ্যাক্সেসযোগ্য করব তা জানতে চাই।

আমি এখানে এটি কীভাবে করছি:

প্রথমে, এখানে আমার ফাইলের কাঠামো (নিচে নামিয়ে দেওয়া) :

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');

আমি জানি ক্লাস অন্তর্ভুক্ত করার আরও ভাল, বা আরও সঠিক উপায়, তবে এটি কী ছিল তা মনে করতে পারছি না। এখনও এটি দেখার জন্য সময় পান নি, তবে আমি মনে করি এটি কিছু ছিল autoload। এরকম কিছু...

configure.php
এখানে আমি মূলত কিছু php.ini -poperties ওভাররাইড করি এবং সাইটের জন্য কিছু অন্যান্য বৈশ্বিক কনফিগারেশন করি

কানেক্ট.এফপি
আমি সংযোগটি একটি ক্লাসে রেখেছি যাতে অন্যান্য ক্লাসগুলি এটির প্রসারিত করতে পারে ...

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();
//

আমি এখানে বিশ্বাস করি যে আমি সম্প্রতি ওওপি শিখতে এবং মাইএসকিএলের পরিবর্তে পিডিও ব্যবহার শুরু করার পরে ব্যাপক উন্নতির সুযোগ রয়েছে।
সুতরাং আমি মাত্র কয়েকজন প্রাথমিকের টিউটোরিয়াল অনুসরণ করেছি এবং বিভিন্ন স্টাফ চেষ্টা করেছি ...

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)

আমার sqlQuery- শ্রেণীর ভিতরে , যা extendsআমার connect_pdo- শ্রেণিতে রয়েছে , আমার একটি সার্বজনীন ফাংশন রয়েছে getAreaNameযা আমার ডাটাবেসে অনুরোধটি পরিচালনা করে।
আমি খুব সুন্দর ঝরঝরে মনে করি।

একটি মোহন মত কাজ করে
তাই মূলত আমি এটি কিভাবে করছি।
এছাড়াও, যখনই আমার ক্লাসের মধ্যে না থেকে আমার ডিবি থেকে কিছু আনার দরকার হয়, আমি ঠিক এর মতো কিছু করি:

$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);

যেহেতু আমি সংযোগ_পড.এফপি এর ভিতরে একটি পরিবর্তনশীল মধ্যে সংযোগ স্থাপন করেছি , আমি কেবল এটি উল্লেখ করেছি এবং আমি যেতে ভাল। এটা কাজ করে। আমি আমার প্রত্যাশিত ফলাফল পেয়েছি ...

তবে তা নির্বিশেষে; আমি যদি এখানে আসি তবে আপনি যদি আমাকে বলতে পারেন তবে আমি সত্যিই প্রশংসা করব। পরিবর্তে আমার কী করা উচিত, যে ক্ষেত্রগুলি আমি উন্নতির জন্য বদলাতে পারলাম ইত্যাদি ...

আমি শিখতে আগ্রহী ...


9
আপনার অ্যাপ্লিকেশনটিতে একবারে একবারে প্রতিটি ফাইল অন্তর্ভুক্ত করার পরিবর্তে আপনার একটি অটোলোডার ব্যবহার করা উচিত ।
লুসিটানিয়ান

উত্তর:


105

লক্ষ

আমি এটি দেখতে হিসাবে, এই ক্ষেত্রে আপনার লক্ষ্য দ্বিগুণ:

  • প্রতি ডাটাবেসটিতে একটি একক / পুনরায় ব্যবহারযোগ্য সংযোগ তৈরি এবং বজায় রাখা
  • নিশ্চিত হয়ে নিন যে সংযোগটি সঠিকভাবে সেট আপ হয়েছে

সমাধান

আমি পিডিও সংযোগের সাথে ডিল করার জন্য বেনামে ফাংশন এবং কারখানার প্যাটার্ন উভয়ই ব্যবহার করার পরামর্শ দেব। এটির ব্যবহারটি দেখতে এরকম দেখাচ্ছে:

$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 );
    }

}

এই পদ্ধতিতে আপনাকে একটি কেন্দ্রীয় কাঠামো থাকতে দেয় যা নিশ্চিত করে যে সংযোগটি কেবলমাত্র যখন প্রয়োজন তখনই তৈরি হয়েছিল। এটি ইউনিট-টেস্টিং এবং রক্ষণাবেক্ষণের প্রক্রিয়াটিকে আরও সহজ করে তুলবে।

এই ক্ষেত্রে সরবরাহকারী বুটস্ট্র্যাপ পর্যায়ে কোথাও পাওয়া যাবে। আপনি ডিবিতে সংযোগের জন্য যে কনফিগারেশনটি ব্যবহার করেন সেটি এই সংস্থানটি একটি স্পষ্ট অবস্থানও দেয়।

মনে রাখবেন এটি একটি অত্যন্ত সরল উদাহরণ । নিম্নলিখিত দুটি ভিডিও দেখে আপনি উপকার পেতে পারেন:

এছাড়াও, আমি পিডিওর ব্যবহার সম্পর্কে একটি সঠিক টিউটোরিয়াল পড়ার দৃ strongly়ভাবে সুপারিশ করব (অনলাইনে খারাপ টিউটোরিয়ালের লগ রয়েছে)।


4
এমনকি পিএইচপি 5.3 EOL এ আসছে appro পুরানো পিএইচপি সংস্করণ সহ বেশিরভাগ সাইটগুলি আসলে ওয়ার্ডপ্রেসের জন্য সস্তার হোস্টিং। পেশাগত বিকাশের উপর প্রাক-5.3 পরিবেশের প্রভাব (তারা এই জাতীয় স্নিপেটগুলি থেকে উপকৃত হবে) তারা নগণ্য, আমার অনুমান অনুসারে।
tereško

4
@ থেলোলক্যাট আমি আপনার সাথে একমত এটা তোলে হয় বেশী বা কম একই উত্তর। এটি যদি আপনি দেখতে না পান যে এটি সম্পূর্ণ আলাদা।
PeeHaa

4
@ থেললক্যাট, তারপরে আপনার শিখতে হবে নির্ভরতা ইনজেকশন কী। পরিবর্তে নিজেকে বিব্রত করা। উপভোগ্যভাবে যথেষ্ট, উপরের পোস্টের দ্বিতীয় ভিডিও (শিরোনাম: "জিনিসগুলির জন্য দেখবেন না" ) আসলে ডিআই কী এবং কীভাবে এটি ব্যবহার করবেন তা ব্যাখ্যা করেছে ... তবে অবশ্যই আপনি এ জাতীয় তুচ্ছ জিনিসগুলির জন্য খুব উন্নত।
তেরেখো

4
এটি একটি পুরানো উত্তর, তবে একটি ভাল - এবং মাইএসকিএল পিডো-র শেষে একটি দুর্দান্ত লিঙ্ক
স্ট্রবেরি

4
@ এমনকি আপনি পিডিও কীভাবে ব্যবহার করবেন তা শিখিয়ে প্রথমে শুরু করা উচিত। আমি এই টিউটোরিয়ালটি সুপারিশ করব: wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers , কারণ এটি mysql_*PDO থেকে মাইগ্রেট করতে চায় এমন লোকদের জন্য সঠিকভাবে তৈরি করা হয়েছে। তারপরে আপনি ফিরে আসতে পারেন এবং এই সমাধানগুলি দেখতে পারেন, যা ইতিমধ্যে পিডিও ব্যবহার করে এমন ব্যক্তিদের উদ্দেশ্যে, তবে একাধিক শ্রেণীর মধ্যে ডিবি সংযোগ ভাগ করার একটি উপায় প্রয়োজন।
tereško

24

আমি $_SESSIONবিশ্বব্যাপী আপনার ডিবি সংযোগ অ্যাক্সেস ব্যবহার না করার পরামর্শ দেব ।

আপনি কয়েকটি জিনিসগুলির মধ্যে একটি করতে পারেন ( সর্বোত্তম অভ্যাসের নিকৃষ্টতম ক্রমে ):

  • আপনার ফাংশন এবং ক্লাসের অভ্যন্তর $dbhব্যবহার করে অ্যাক্সেস করুনglobal $dbh
  • একটি সিঙ্গলটন রেজিস্ট্রি ব্যবহার করুন এবং বিশ্বব্যাপী অ্যাক্সেস করুন, এর মতো:

    $registry = MyRegistry::getInstance();
    $dbh = $registry->getDbh();
    
  • প্রয়োজনীয় ক্লাসগুলিতে ডাটাবেস হ্যান্ডলারটি ইনজেক্ট করুন, এর মতো:

    class MyClass {
        public function __construct($dbh) { /* ... */ }
    }
    

আমি সর্বশেষে একটি সুপারিশ করব। এটি নির্ভরতা ইনজেকশন (ডিআই), নিয়ন্ত্রণের বিপরীতটি (আইওসি), বা কেবল হলিউডের নীতি হিসাবে পরিচিত (আমাদের কল করবেন না, আমরা আপনাকে কল করব)।

তবে এটি কিছুটা উন্নত এবং ফ্রেমওয়ার্ক ছাড়াই আরও "ওয়্যারিং" প্রয়োজন। সুতরাং, যদি নির্ভরতা ইঞ্জেকশনটি আপনার পক্ষে খুব জটিল হয় তবে একগুচ্ছ বিশ্বব্যাপী ভেরিয়েবলের পরিবর্তে একটি একক রেজিস্ট্রি ব্যবহার করুন।


সুতরাং আমি আমার sqlQueryক্লাসটি সেশনটিতে সেট করার পরে যখন আমি তার ক্লাসটি বিশ্বব্যাপী অ্যাক্সেস করব connect_pdo?
টমাসক

7

আমি সম্প্রতি আমার নিজের মতো একটি উত্তর / প্রশ্নে এসেছি। যদি কেউ আগ্রহী হয় তবে আমি এটিই করেছি:

<?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 */);

এবং টাইপ-হিন্টিং যদি আপনি এটি ব্যবহার করে থাকেন (\ গ্রন্থাগার \ পিডিও $ ডিবি)।

এটি গ্রহণযোগ্য উত্তর এবং আপনার উভয়েরই মতো; তবে এটির একটি উল্লেখযোগ্য সুবিধা রয়েছে। এই কোডটি বিবেচনা করুন:

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

$STH = $DB->prepare("SELECT * FROM users WHERE user = ?");
$STH->execute(array(25));
$User = $STH->fetch();

এটি সাধারণ পিডিওর মতো দেখাতে পারে (এটি \Library\কেবলমাত্র তার দ্বারা পরিবর্তিত হয় ) তবে আপনি প্রথম পদ্ধতিটি কল না করা অবধি এটি বস্তুটি আরম্ভ করবে না, এটি যে কোনও ক্ষেত্রেই। এটি এটিকে আরও অনুকূলিত করে তোলে, যেহেতু PDO অবজেক্ট তৈরি করা কিছুটা ব্যয়বহুল। এটি একটি স্বচ্ছ শ্রেণি, বা একে কী ভূত বলা হয়, অলস লোডিংয়ের একটি রূপ । আপনি PD DB কে একটি সাধারণ পিডিও উদাহরণ হিসাবে চিকিত্সা করতে পারেন, এটি পাশ করে দেওয়া, একই ক্রিয়াকলাপ ইত্যাদি etc.


একে "ডেকোরেটার প্যাটার্ন" বলা হয়
ইয়াং

0
$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();
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.