PDO সমাপ্তি সংযোগ


120

মাইএসকিউএলআইয়ের সাথে তুলনা করে পিডিও সম্পর্কিত কেবল একটি সহজ প্রশ্ন।

মাইএসকিউএলআই সহ, আপনি যে সংযোগটি করতে পারেন তা বন্ধ করতে:

$this->connection->close();

তবে পিডিওর সাথে এটিতে লিখিতভাবে আপনি সংযোগটি খুলছেন:

$this->connection = new PDO();

তবে আপনি যে সংযোগটি সেট করেছেন তা বন্ধ করতে null

$this->connection = null;

এটি কি সঠিক এবং এটি কি PDO সংযোগটি মুক্ত করবে? (আমি জানি এটি যেমন সেট করা nullআছে তেমন করে close) = nullসংযোগ বিচ্ছিন্ন করার মতো পিডিও কি সহজ ? বা সংযোগটি বন্ধ করার কোনও ফাংশন আছে?


11
আমি যে কারণে জিজ্ঞাসা করছি তা নিশ্চিত না যে আমি সংযোগটি সঠিকভাবে বন্ধ করে দিচ্ছি কিনা not তবে সত্যিই কেবল আগ্রহী নয়
লিয়াম সর্সবি

2
আপনার পিএইচপি স্ক্রিপ্ট কার্যকর হওয়া বন্ধ করলে ডাটাবেস সংযোগটি স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায়।
মার্টিন বিন

3
আপনি যদি এটি ব্যবহার করে শেষ করে থাকেন তবে কেন এগিয়ে যান এবং এটিকে সমাপ্ত করবেন না, বিশেষ করে যদি আপনি ডাটাবেসের সাথে আলাপচারিতা শেষ করে কিছু সময় গ্রহণকারী কোড পান is যদিও, স্ক্রিপ্টটি শেষ হওয়ার অপেক্ষায় সমস্যাটি আমি সত্যিই দেখতে পাচ্ছি না (ডিবি সার্ভারের সাথে সংযোগ হ্রাস করা ব্যতীত K)
কাইরান

3
github.com/php/php-src/blob/master/ext/pdo/pdo_pb_dbh.c এটি কীভাবে কাজ করে তা নিজের জন্য সন্ধান করুন: পি
ফ্লোসকুলাস

23
সমস্ত পিএইচপি স্ক্রিপ্টগুলি স্বল্পস্থায়ী নয়। সেখানে পিএইচপি ডেমন রয়েছে। আমি ব্যক্তিগতভাবে স্পষ্ট করার জন্য এটি দুর্দান্ত জিনিস বলে আমি মনে করি।
ডেটাউজার 21

উত্তর:


146

ডকুমেন্টেশন অনুসারে আপনি সঠিক ( http://php.net/manual/en/pdo.connections.php ):

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

নোট করুন যে আপনি যদি পিডিও অবজেক্টটিকে অবিচ্ছিন্ন সংযোগ হিসাবে শুরু করেন তবে এটি স্বয়ংক্রিয়ভাবে সংযোগটি বন্ধ করবে না।


4
আমার যদি এমন প্রক্রিয়া শেষ না হয় তবে কী হবে? যেমন ওয়েবসকেট অবিচ্ছিন্ন সংযোগ ব্যবহার না করার উপায় আছে কি?
রাফায়েল মনি

1
একটি স্ক্রিপ্টে অবিচ্ছিন্ন সংযোগের জন্য যা দীর্ঘ সময় ধরে চলে আপনি উদ্দেশ্যমূলকভাবে (বা দুর্ঘটনাক্রমে) সংযোগগুলি একটি সময়সীমা (যেমন my.ini) এর সাথে নিহত করতে পারেন, বা অন্যান্য বেশ কয়েকটি কারণে। যখন কোনও জিজ্ঞাসা সংযোগ করা বা চলমান থাকে তখন কোনও ত্রুটি ধরুন এবং যদি এটি "মাইএসকিউএল চলে গেছে", আবার সংযোগ দেওয়ার চেষ্টা করুন বা কোয়েরিটি দ্বিতীয়বার চালানোর চেষ্টা করুন।
ফ্র্যাঙ্ক ফোর্ট

1
Note that if you initialise the PDO object as a persistent connection it will not automatically close the connectionতবে যদি কোনও সংযোগ স্থির থাকে এবং আমি স্ক্রিপ্টটি শেষ হওয়ার আগে স্পষ্টভাবে এটিতে NULL কে কল করি, এটি স্থির থাকলেও এটি বন্ধ হয়ে যাবে, সঠিক?
টোনিক্স

1
@ টোনিক্স না, এটি প্রকাশ করা উচিত (অন্য স্ক্রিপ্টের জন্য উপলব্ধ করা হয়েছে), তবে বন্ধ নয়।
বেনিয়ামিন

2
@ টোনিক্স আমি তাই মনে করি, হ্যাঁ। অবিচ্ছিন্ন সংযোগগুলির বিষয়ে পিএইচপি ম্যানুয়াল থেকে উদ্ধৃতি : " সতর্কতা অবিচ্ছিন্ন সংযোগগুলি ব্যবহার করার সময় মনে রাখার জন্য আরও কয়েকটি অতিরিক্ত ক্যাভেট রয়েছে One তারপরে একই সংযোগটি ব্যবহার করে পরবর্তী স্ক্রিপ্টগুলি অনির্দিষ্টকালের জন্য অবরুদ্ধ হয়ে যাবে এবং আপনি HTD সার্ভার বা ডাটাবেস সার্ভারটি পুনরায় চালু করার প্রয়োজন হতে পারে। "
বেনিয়ামিন

46
$conn=new PDO("mysql:host=$host;dbname=$dbname",$user,$pass);
    // If this is your connection then you have to assign null
    // to your connection variable as follows:
$conn=null;
    // By this way you can close connection in PDO.

11
আইএমএইচওও আমি মনে করি এটি খুব খারাপ প্যাটার্ন, বিশেষত যখন কোনও বিকাশকারী পিডো রেফারেন্সের কয়েকটি কপি সঞ্চয় করতে পারে। $ a = নতুন পিডিও (...); $ খ = $ এ; $ a = নাল; সেখানে, আপনার PDO অবজেক্ট চিরকাল খোলা থাকবে (ডেমনের মতো পিএইচপি প্রোগ্রামে)। এটি বিশেষত সত্য যখন PDO রেফারেন্স ফাংশন এবং অবজেক্টের বৈশিষ্ট্যগুলি জুড়ে ভ্রমণ করে এবং আপনি কখনই সেগুলি সরিয়ে দেওয়ার বিষয়ে নিশ্চিত হন না।
গ্যাব্রিয়েল

33
পিডিওতে একটি -> বন্ধ () পদ্ধতি থাকা উচিত।
গ্যাব্রিয়েল

5
পিডিও অপছন্দ করার আরেকটি কারণ।
জোসে কার্লোস পিএইচপি

6
@ গ্যাব্রিয়েল - আমি পরামর্শ দিচ্ছি যে "বেশ কয়েকটি অনুলিপি সংরক্ষণ করা" আরও খারাপ প্যাটার্ন।
রিক জেমস

4
আপনি যদি এই দুটি সারির মধ্যে PDOStatement অবজেক্ট তৈরি করে থাকেন (তবে এটি প্রতিটি ব্যবহারিক পরিস্থিতিতে) কাজ করে না। সংযোগটি বন্ধ করতে, আপনাকে PDO অবজেক্ট এবং PDOStatement অবজেক্ট উভয়ই বাতিল করতে হবে। এখানে দেখুন: php.net/manual/en/pdo.connections.php#114822
ইলমারি

8

এটি কেবল শূন্যতার সাথে সংযোগ স্থাপনের চেয়ে বেশি। ডকুমেন্টেশন যা বলে তা হতে পারে তবে এটি মাইএসকিএল-এর পক্ষে সত্য নয়। সংযোগটি আরও দীর্ঘকাল ধরে থাকবে (60০ এর দশক শুনেছি, তবে এটি কখনও পরীক্ষিত হয়নি)

আপনি যদি এখানে সম্পূর্ণ ব্যাখ্যা করতে চান তবে সংযোগগুলি সম্পর্কে এই মন্তব্যটি দেখুন https://www.php.net/manual/en/pdo.connections.php#114822

সংযোগটি বাধ্য করার জন্য আপনাকে এমন কিছু করতে হবে

$this->connection = new PDO();
$this->connection->query('KILL CONNECTION_ID()');
$this->connection = null;

আপনার উত্তর করার জন্য আপনাকে ধন্যবাদ। প্রশ্নটি বেশ কিছুক্ষণ আগে থেকেই হয়েছিল তবে সংযোগ সম্পর্কে আপনার অধিকার।
লিয়াম সর্সবি

আমি প্রকৃতপক্ষে একমত নই যে পিএইচপি এর মাধ্যমে টিসিপি সংযোগের সাথে জগাখিচুড়ি করা ভাল ধারণা। সমস্ত নিম্ন স্তরের টিসিপি সংযোগ হ্যান্ডলিং দূরে থাকে যাতে রানটাইমের সময় আমাদের কেবল উচ্চ স্তরের শ্রেণি এবং অবজেক্টগুলির সাথে ডিল করতে হয়। পিএইচপি একটি অনুরোধ ভিত্তিক ভাষা (যেমন আপনি সম্ভবত জানেন) তাই ডিবিতে একটি সম্ভাব্য অবিচ্ছিন্ন সংযোগ হত্যার ফলে ব্যবহারকারীদের জন্য অপ্রত্যাশিত সমস্যা / সমস্যা দেখা দিতে পারে। আপনি যে সংযোগটির সাথে লিঙ্কটি ব্যবহার করেছেন সম্ভবত ফলস্বরূপ সংযোগটি অন্য অনুরোধের দ্বারা ব্যবহারের জন্য উন্মুক্ত রাখার ফলস্বরূপ ফলস্বরূপ এটি আমার প্রত্যাশিত আচরণ হবে thought
লিয়াম সর্সবি

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

আমি এই ব্যাখ্যাটি পেয়েছি: stackoverflow.com/a/18277327/1315873
ফিলি

7

আমি "$ সংযোগ = নাল;" এর পরিবর্তে আরও স্ব-ডকুমেন্টিংয়ের নির্দেশনা অর্জনের জন্য একটি উত্পন্ন ক্লাস তৈরি করেছি।

class CMyPDO extends PDO {
    public function __construct($dsn, $username = null, $password = null, array $options = null) {
        parent::__construct($dsn, $username, $password, $options);
    }

    static function getNewConnection() {
        $conn=null;
        try {
            $conn = new CMyPDO("mysql:host=$host;dbname=$dbname",$user,$pass);
        }
        catch (PDOException $exc) {
            echo $exc->getMessage();
        }
        return $conn;
    }

    static function closeConnection(&$conn) {
        $conn=null;
    }
}

সুতরাং আমি আমার কোডটির মধ্যে কল করতে পারি:

$conn=CMyPDO::getNewConnection();
// my code
CMyPDO::closeConnection($conn);

1
আপনি সিএমইপিডিও :: __ নির্মাণ () পদ্ধতিটি ব্যক্তিগত তৈরি করতে পারেন এবং সেখানে
সিঙ্গেলটন

হ্যাঁ, এটি সম্ভাব্য। আপনি যদি একবারে একাধিক ডাটাবেস ব্যবহার করেন তবে আপনাকে অন্য পদ্ধতিতে সংযোগের তথ্যও সরবরাহ করতে হবে। পার্থক্যটি হ'ল ন্যূনতম, কেবলমাত্র আপনার কাছে ইনস্ট্যান্স পদ্ধতিগুলি কল করার জন্য আরও দীর্ঘতর নির্দেশনা রয়েছে।
ফিল্ড করুন

@ আদিত্যহাজারে আপনি একটি সাবক্লাসে ব্যক্তিগত একটি সুপারক্লাসের সর্বজনীন পদ্ধতি তৈরি করতে পারবেন না
নিকডনক

@ নিকডনক, আপনি ঠিক বলেছেন আমার অভিপ্রায়টি হ'ল একটি স্বতন্ত্র শ্রেণি সিএমইপিডিও তৈরি করা (এটি পিডিও প্রসারিত না করে) এবং তারপরে সিএমইপিডিওর একটি প্রাইভেট কনস্ট্রাক্টরের ভিতরে ডাটাবেসের একটি উদাহরণ তৈরি করা (নতুন পিডিও ($ ডিএসএন, $ ডুবসার, $ ডিবিপাস)) বর্গ তৈরি করে কেবলমাত্র একটি উদাহরণস্বরূপ অ্যাপ্লিকেশন জুড়ে উপলব্ধ (একক ডিজাইন প্যাটার্ন)।
আদিত্য হাজারে

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

-1
<?php if(!class_exists('PDO2')) {
    class PDO2 {
        private static $_instance;
        public static function getInstance() {
            if (!isset(self::$_instance)) {
                try {
                    self::$_instance = new PDO(
                        'mysql:host=***;dbname=***',
                        '***',
                        '***',
                        array(
                            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_general_ci",
                            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION
                        )
                    );
                } catch (PDOException $e) {
                    throw new PDOException($e->getMessage(), (int) $e->getCode());
                }
            }
            return self::$_instance;
        }
        public static function closeInstance() {
            return self::$_instance = null;
        }
    }
}
$req = PDO2::getInstance()->prepare('SELECT * FROM table');
$req->execute();
$count = $req->rowCount();
$results = $req->fetchAll(PDO::FETCH_ASSOC);
$req->closeCursor();
// Do other requests maybe
// And close connection
PDO2::closeInstance();
// print output

সম্পূর্ণ উদাহরণ, কাস্টম ক্লাস PDO2 সহ।


1
দয়া করে হয় আপনার কোড থেকে ধরার চেষ্টা সরিয়ে ফেলুন বা এখানে প্রদর্শিত হিসাবে একটি নতুন থ্রো যুক্ত করুন । এই মুহুর্তে আপনার কোড ব্যতিক্রম এবং সাধারণভাবে ত্রুটি প্রতিবেদন উভয়কেই আপত্তিজনকভাবে ব্যবহার করে
আপনার প্রচলিত সংবেদন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.