2010-12-16 10 views
12

पर एक सदस्य फ़ंक्शन तैयार() पर कॉल करें, मैं एक PHP फ़ंक्शन लिखने की कोशिश कर रहा हूं। यह बहुत ही सरल है। यह सिर्फ एक तैयार कथन है जो डेटाबेस से पूछताछ करता है, लेकिन मैं इसे काम पर नहीं ला सकता हूं। मैं एक गैर-ऑब्जेक्ट पर सदस्य फ़ंक्शन तैयार() को त्रुटि कॉल प्राप्त करता रहता हूं। यहां कोड है:गैर-ऑब्जेक्ट PHP सहायता

$DBH = new mysqli("host", "test", "123456", "dbname"); 
function selectInfo($limit, $offset){ 
    $stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?"); 
    $stmt->bind_param("ii", $limit, $offset); 
    $stmt->execute(); 
    } 
selectInfo(); 

जब भी मैं फ़ंक्शन को कॉल करता हूं तो मुझे वह त्रुटि मिलती है। क्या कोई मदद कर सकता है?

उत्तर

43

यह एक scoping त्रुटि है। आप $DBH एक वैश्विक चर बना रहे हैं। तो जब आप फ़ंक्शन दर्ज करते हैं, तो वैश्विक चर उपलब्ध नहीं है। आपके पास 5 वास्तविक विकल्प हैं। वैश्विक कीवर्ड

function doSomething() { 
    global $DBH; 
    //... 

यह एक अच्छा विचार है, क्योंकि यह रखरखाव करता है और एक PITA परीक्षण नहीं है

1. का प्रयोग करें। कल्पना करें कि उस फ़ंक्शन कॉल को डीबग करने का प्रयास करें। अब आप जहां $DBH यह पता लगाने की क्या हो रहा है की कोशिश करने परिभाषित किया गया है पता लगाने के जाने की जरूरत है ...

2. $DBH एक पैरामीटर बनाने कार्य करने के लिए

function doSomething(MySQLi $DBH) { 

यह किया जा रहा है का लाभ दिया है स्पष्ट। लेकिन यह अभी भी अच्छा नहीं है क्योंकि कॉलिंग कोड को वैश्विक चर का ट्रैक रखने की आवश्यकता है।

3. एक समारोह को "मिल" $DBH वस्तु

function getDBH() { 
    static $DBH = null; 
    if (is_null($DBH)) { 
     $DBH = new mysqli(...); 
    } 
    return $DBH; 
} 

function doSomething() { 
    $DBH = getDBH(); 
} 

यह वैश्विक चर समस्या को हल पूरी तरह से हो रही है का लाभ दिया है बनाएँ। लेकिन कई कनेक्शन होना या अन्य कनेक्शन के लिए किसी भी कोड का पुन: उपयोग करना भी मुश्किल है।

4. डेटाबेस का उपयोग

class Database { 
    public function __construct($host, $user, $pass) { 
     $this->DBH = new MySQli($host, $user, $pass); 
    } 
    public function doSOmething() { 
     $this->DBH->foo(); 
    } 
} 

यह आप के लिए सब कुछ समाहित रैप करने के लिए एक कक्षा बनाएं। सभी डेटाबेस एक्सेस एक ही कक्षा के माध्यम से चले जाएंगे, इसलिए आपको ग्लोबल वैरिएबल एक्सेस या किसी अन्य चीज़ के बारे में चिंता करने की आवश्यकता नहीं है। पहले से बने वर्ग/ढांचे

के बाद आप इसे अपने आप को करने के बारे में चिंता करने की जरूरत नहीं है यह, सबसे अच्छा विकल्प है

5. का प्रयोग करें।

डाटाबेस पहुँच क्लास:

  • A quick google search to get you started
  • Doctrine ORM - पूर्ण ORM के साथ एक पूरा डेटाबेस का उपयोग पुस्तकालय (वस्तु मानचित्रण)
  • ADODB - एक डेटाबेस नास्तिक डेटाबेस का उपयोग पुस्तकालय
  • Pear MDB2 - एक और डेटाबेस एक्सेस लाइब्रेरी

पूर्ण फ़्रेमवर्क:

  • Zend Framework
  • Lithium Framework
  • Code Igniter
  • (वास्तव में अभी भी बहुत सा, मैं नहीं किसी भी अधिक लिस्टिंग परेशान करने के लिए जा रहा हूँ कर रहे हैं के बाद से है कि एक और सवाल है सब एक साथ ...)

वास्तव में, विकल्प अंतहीन हैं। अपनी पसंद की कुछ ढूंढें, और इसके साथ चिपके रहें। यह वास्तव में आपके जीवन को आसान बना देगा ...

शुभकामनाएं!

+1

+1 विकल्पों का अच्छा सेट। –

+0

यह मेरे लिए काम नहीं किया: http://stackoverflow.com/questions/40080426/fatal-error-call-to-a-member-function-prepare-on-a-non-object-in-but-value – fresher

3

फ़ंक्शन में global $DBH; जोड़ने का प्रयास करें, या इसे फ़ंक्शन के पैरामीटर में जोड़ें।

3
selectInfo($DBH); 

function selectInfo($DBH,$limit, $offset){ 
    $stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?"); 
    $stmt->bind_param("ii", $limit, $offset); 
    $stmt->execute(); 
    } 
7

$DBH दायरे में नहीं है। आप या तो समारोह में वैश्विक रूप $DBH परिभाषित करना चाहते हैं:

$DBH = new mysqli("host", "test", "123456", "dbname"); 
function selectInfo($limit, $offset){ 
    global $DBH; 
    $stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?"); 
    $stmt->bind_param("ii", $limit, $offset); 
    $stmt->execute(); 
} 

या के रूप में ircmaxell अपने उत्कृष्ट जवाब में बताया एक समारोह जो $DBH की एक स्थिर उदाहरण देता है।

+0

धन्यवाद। मैं इसे वैश्विक कैसे बनाऊंगा और फिर भी चीजों को सुरक्षित रखूंगा? क्या मैं एक फ़ंक्शन में कनेक्शन लपेटूंगा और उसके बाद फ़ंक्शन कनेक्ट() {new myqsli ("host", "test", "123456", "dbname")} $ DBH = नया कनेक्ट(); (कनेक्शन चर वास्तव में किसी अन्य फ़ाइल में छिपे हुए हैं।) – mcbeav

+0

हाँ, मैं कुछ प्रकार का कार्य करता हूं और वहां से कनेक्शन लेता हूं। – Jim

+0

@ircmaxell हो गया। आप निश्चित रूप से सही कह रहे हैं। प्रत्येक विधि कॉल के लिए एक नया कनेक्शन बनाना एक बुरा विचार है। – Jim

3

यह बस है। $DBHselectInfo() फ़ंक्शन के भीतर मौजूद नहीं है। वैश्विक क्षेत्र में परिभाषित वैरिएबल फ़ंक्शन के भीतर दिखाई नहीं देगा और इसके विपरीत। मैन्युअल पृष्ठों पर variables scope के बारे में और पढ़ें।

इसे कैसे हल करें? उस चर को फ़ंक्शन के तर्क के रूप में पास करें:

$dbh = new MySQLi(...); 

function selectInfo(MySQLi $dbh, $limit, $offset) { 
    $stmt = $dbh->prepare(...); 
    ... 
} 
3

सुनिश्चित करें कि कनेक्शन सफल है।

$DBH = @new mysqli("host", "test", "123456", "dbname"); 

if ($DBH->connect_errno) { 
    die('Connect Error: ' . $DBH->connect_errno); 
} 

या

$DBH = @mysqli_connect("host", "test", "123456", "dbname"); 

if (!$DBH) { 
    die('Connect Error: ' . mysqli_connect_errno()); 
} 
0

बनाना $ DBH वैश्विक स्वस्थ नहीं है ... छोड़कर आप अपने $ DBH कक्षा में संरक्षित कर सकते हैं और यह सेट शून्य .. और इसका इस्तेमाल कर सकते हैं कि ..

0
class PDOconnect extends PDO{ 

संरक्षित $ चोर = शून्य;

public function __construct(){ 
       try {  

        $this->con= new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD); //our new PDO Object 

         $this->con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);      
         $this->con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);      
         $this->con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
         echo "hi.. you are connected succcessfully..."; 
        } 
संबंधित मुद्दे