2012-03-01 15 views
16

में कस्टम कक्षाएं ऐसा लगता है कि कोडइग्निटर के साथ शुरुआती लोगों के लिए यह एक बहुत ही आम समस्या है, लेकिन अब तक जो समाधान मैंने पाया है, मेरी समस्या के लिए बहुत प्रासंगिक नहीं है। विषय की तरह मैं कहता हूं कि मैं कोडइग्निटर में एक कस्टम क्लास शामिल करने की कोशिश कर रहा हूं।कोडइग्निटर

मैं नीचे कक्षा की कई वस्तुओं को बनाने और उन्हें सरणी में रखने की कोशिश कर रहा हूं, इस प्रकार मुझे कक्षा में मॉडल उपलब्ध होने की आवश्यकता है।

मैंने कोडइग्निटर के भीतर लोड (लाइब्रेरी-> लोड ('माइक्लास') फ़ंक्शंस का उपयोग करने का प्रयास किया है, जो कि मॉडल के बाहर कक्षा के किसी ऑब्जेक्ट को बनाने की कोशिश करता है। यह स्पष्ट रूप से एक समस्या है निर्माता कई मापदंडों की उम्मीद है।

समाधान मैं अब तक मिल गया है

  1. एक सरल php शामिल है जो काफी ठीक लग रहा है, लेकिन जब से मैं CodeIgniter के लिए नया हूँ मुझे यकीन है कि मैं बनाना चाहते है मैं इसे जितना संभव हो रहा हूं।
  2. सुझाए गए here के रूप में एक "रैपर वर्ग" बनाना, हालांकि मुझे अनिश्चितता है कि मैं इसे कैसे कार्यान्वित करूंगा।

वर्ग मैं शामिल करना चाहते हैं, User.php

<?php if (! defined('BASEPATH')) exit('No direct script access allowed'); 
class User{ 
    public $ID = 0; 
    public $username = 0; 
    public $access_lvl = 0; 
    public $staff_type = 0; 
    public $name = 0;  

    public function __construct($ID, $username, $access_lvl, $staff_type, $name) 
    { 
     $this->ID = $ID; 
     $this->username = $username; 
     $this->access_lvl = $access_lvl; 
     $this->staff_type = $staff_type; 
     $this->name = $name; 
    } 

    public function __toString() 
    { 
     return $this->username; 
    } 
} 
?> 

विधि (मॉडल) जो User.php

function get_all_users() 
{ 
    $query = $this->db->get('tt_login'); 
    $arr = array(); 

    foreach ($query->result_array() as $row) 
    { 
     $arr[] = new User 
     (
      $row['login_ID'], 
      $row['login_user'], 
      $row['login_super'], 
      $row['crew_type'], 
      $row['login_name'] 
     ); 
    }  

    return $arr; 
} 

और अंत में नियंत्रक की जरूरत है ,

function index() 
{ 
     $this->load->library('user'); 
     $this->load->model('admin/usersmodel', '', true);    

     // Page title 
     $data['title'] = "Some title"; 
     // Heading 
     $data['heading'] = "Some heading"; 
     // Data (users) 
     $data['users'] = $this->usersmodel->get_all_users(); 

उत्तर

15

आप PHP संस्करण है, तो> = 5.3 आप नामस्थान और autoloading सुविधाओं का उपयोग हो सकता है।

लाइब्रेरी फ़ोल्डर में एक साधारण ऑटोलोडर लाइब्रेरी।

<?php 
class CustomAutoloader{ 

    public function __construct(){ 
     spl_autoload_register(array($this, 'loader')); 
    } 

    public function loader($className){ 
     if (substr($className, 0, 6) == 'models') 
      require APPPATH . str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php'; 
    } 

} 
?> 

मॉडल डीआईआर में उपयोगकर्ता ऑब्जेक्ट। (मॉडल/User.php)

<?php 
namespace models; // set namespace 
if (! defined('BASEPATH')) exit('No direct script access allowed'); 
class User{ 
... 
} 

और नए उपयोगकर्ता के बजाय ... नए मॉडल \ उपयोगकर्ता (...)

function get_all_users(){ 
    .... 
    $arr[] = new models\User(
    $row['login_ID'], 
    $row['login_user'], 
    $row['login_super'], 
    $row['crew_type'], 
    $row['login_name'] 
    ); 
    ... 
} 

और नियंत्रक में सिर्फ कॉल करने के लिए सुनिश्चित करें इस तरह customautoloader:

function index() 
{ 
     $this->load->library('customautoloader'); 
     $this->load->model('admin/usersmodel', '', true);    

     // Page title 
     $data['title'] = "Some title"; 
     // Heading 
     $data['heading'] = "Some heading"; 
     // Data (users) 
     $data['users'] = $this->usersmodel->get_all_users(); 
+0

धन्यवाद, एक आकर्षण की तरह काम किया। –

+1

नामस्थान के बिना इसका उपयोग करने की विधियां क्या हैं? या क्या नामस्थान हमें सर्वर पर फ़ाइल संरचना के भीतर काम करने की अनुमति देता है जहां हमने अपनी कस्टम कक्षाओं को परिभाषित किया है? – David

3

कक्षा फ़ाइल सहित एक बुरा दृष्टिकोण नहीं है।

हमारी परियोजनाओं में, हम वही करते हैं, एमवीसी में एक और परत जोड़ें, और यह एक सेवा परत है जिसे नियंत्रक कहते हैं और सेवा मॉडल को कॉल करती है। हमने बिजनेस लॉजिक सेपरेट जोड़ने के लिए इस परत को पेश किया।

अब तक, हम इसका उपयोग कर रहे हैं, और हमारा उत्पाद भी बड़ा हो गया है, और फिर भी हमें अतीत में बनाई गई फ़ाइलों को शामिल करने के निर्णय में कोई कठिनाई नहीं है।

+3

@itachi: जो आपको लगता है, आवश्यक नहीं है, दुनिया वही देखती है। मेरा जवाब है कि उपयोगकर्ता को विश्वास दिलाएं कि फ़ाइल को सीधे शामिल करना एक दोषपूर्ण विचार नहीं है। :) – linuxeasy

+0

मूल रूप से यह है कि आप जावा सहित किसी अन्य भाषा में क्या करते हैं। एकमात्र अंतर यह है कि आप उन्हें 'आयात' कहते हैं और यहां आप उन्हें ' – linuxeasy

1

कोडिनेटर के पास व्यक्तिगत कक्षाओं को तुरंत चालू करने के लिए एक आम कार्य है।

यह load_class कहा जाता है(), /system/core/Common.php

समारोह में पाया;

/** 
* Class registry 
* 
* This function acts as a singleton. If the requested class does not 
* exist it is instantiated and set to a static variable. If it has 
* previously been instantiated the variable is returned. 
* 
* @access public 
* @param string the class name being requested 
* @param string the directory where the class should be found 
* @param string the class name prefix 
* @return object 
*/ 

हस्ताक्षर

load_class($class, $directory = 'libraries', $prefix = 'CI_') 

यह का एक उदाहरण इस्तेमाल किया जा रहा है, जब आप show_404() समारोह कहते हैं।

+2

' कहते हैं, जहां तक ​​मैं कह सकता हूं कि मुझे इस दृष्टिकोण के साथ मॉडल के बाहर एक अतिरिक्त वस्तु के साथ भी छोड़ा गया है? जब तक कि इससे बचने का कोई तरीका न हो, मैं अनुमान लगा रहा हूं कि मुझे मानक के लिए जाना होगा। –

6

कोडइग्निटर वास्तव में वास्तविक वस्तुओं का समर्थन नहीं करता है। सभी पुस्तकालय, मॉडल और ऐसे, सिंगलेट्स की तरह हैं।

कोडइग्निटर संरचना को बदले बिना जाने के 2 तरीके हैं।

  1. बस उस फ़ाइल को शामिल करें जिसमें कक्षा है, और इसे उत्पन्न करें।

  2. लोड-> लाइब्रेरी या load_class() विधि का उपयोग करें, और केवल नई ऑब्जेक्ट बनाएं। इसका नकारात्मक पक्ष यह है कि यह हमेशा 1 अतिरिक्त वस्तु उत्पन्न करेगा, जिसकी आपको आवश्यकता नहीं है। लेकिन अंत में लोड विधियों में फ़ाइल भी शामिल होगी।

एक और संभावना, जिसके लिए कुछ अतिरिक्त काम की आवश्यकता होगी, उपयोगकर्ता_फैक्टरी लाइब्रेरी बनाना है। फिर आप फ़ाइल के नीचे ऑब्जेक्ट जोड़ सकते हैं, और कारखाने से इसके नए उदाहरण बना सकते हैं।

मैं खुद फैक्टरी पैटर्न का एक बड़ा प्रशंसक हूं, लेकिन यह एक निर्णय है जिसे आपको स्वयं बनाना है।

मुझे आशा है कि इससे आपकी मदद मिलेगी, अगर आपके पास कोई प्रश्न है जो कार्यान्वयन से संबंधित हैं, तो बस मुझे बताएं।

+2

क्या आप मुझे इस दृष्टिकोण के किसी भी उदाहरण से लिंक कर सकते हैं? –

0

एक संक्षिप्त गूगल खोज के बाद, मैं अपने खुद के autoloader वर्ग बनाने के लिए प्रेरित किया गया था। यह एक हैक का एक सा है, क्योंकि मैं ऑटो-लोडिंग को पूर्ववत करने के लिए कस्टम कोडिग्निटर लाइब्रेरी का उपयोग करता हूं, लेकिन मेरे लिए यह सबसे अच्छा तरीका है, मुझे पता है कि, सभी कक्षाओं को लोड करने के बारे में मुझे पता है, मुझे अपने एप्लिकेशन आर्किटेक्चर दर्शन के समझौता किए बिना , चीजों को करने के कोडिनेटर तरीके में फिट करने के लिए। कुछ लोग तर्क दे सकते हैं कि कोडिनेटर मेरे लिए सही ढांचा नहीं है और यह सच हो सकता है, लेकिन मैं चीजों की कोशिश कर रहा हूं और विभिन्न ढांचे के साथ खेल रहा हूं और सीआई पर काम करते समय, मैं इस समाधान के साथ आया हूं। संपादन शामिल करने के लिए applicaion/config/autoload.php द्वारा 1. ऑटो-लोड नए कस्टम पुस्तकालय:

$autoload['libraries'] = array('my_loader'); 

और किसी भी अन्य पुस्तकालयों आपको आवश्यकता होगी। 2. फिर लाइब्रेरी क्लास My_loader जोड़ें। यह वर्ग प्रत्येक अनुरोध पर लोड हो जाएगा और जब उसका कन्स्ट्रक्टर चलाया जाएगा, तो यह सभी उप-फ़ोल्डर्स के माध्यम से रिकर्सिवली खोज करेगा और आवेदन/सेवा & एप्लिकेशन/मॉडल/डीटीओ फ़ोल्डर्स के अंदर सभी .php फ़ाइलों की आवश्यकता होगी।चेतावनी: फ़ोल्डरों नाम पर डॉट नहीं होना चाहिए, अन्यथा समारोह असफल हो जायेगी

<?php if (! defined('BASEPATH')) exit('No direct script access allowed'); 

class My_loader { 

    protected static $_packages = array(
      'service', 
      'models/dto' 
      ); 

    /** 
    * Constructor loads service & dto classes 
    * 
    * @return void 
    */ 
    public function __construct($packages = array('service', 'models/dto')) 
    { 
     // files to be required 
     $toBeRequired = array(); 

     // itrate through packages 
     foreach ($packages as $package) { 
      $path = realpath(APPPATH . '/' . $package . '/'); 
      $toBeRequired = array_merge($toBeRequired, $this->findAllPhpFiles($path)); 
     } 

     /** 
     * Require all files 
     */ 
     foreach ($toBeRequired as $class) { 
      require_once $class; 
     } 
    } 

    /** 
    * Find all files in the folder 
    * 
    * @param string $package 
    * @return string[] 
    */ 
    public function findAllPhpFiles($path) 
    { 
     $filesArray = array(); 
     // find everithing in the folder 
     $all = scandir($path); 
     // get all the folders 
     $folders = array_filter($all, get_called_class() . '::_folderFilter'); 
     // get all the files 
     $files = array_filter($all, get_called_class() . '::_limitationFilter'); 

     // assemble paths to the files 
     foreach ($files as $file) { 
      $filesArray[] = $path . '/' . $file; 
     } 
     // recursively go through all the sub-folders 
     foreach ($folders as $folder) { 
      $filesArray = array_merge($filesArray, $this->findAllPhpFiles($path . '/' . $folder)); 
     } 

     return $filesArray; 
    } 

    /** 
    * Callback function used to filter out array members containing unwanted text 
    * 
    * @param string $string 
    * @return boolean 
    */ 
    protected static function _folderFilter($member) { 
     $unwantedString = '.'; 
     return strpos($member, $unwantedString) === false; 
    } 

    /** 
    * Callback function used to filter out array members not containing wanted text 
    * 
    * @param string $string 
    * @return boolean 
    */ 
    protected static function _limitationFilter($member) { 
     $wantedString = '.php'; 
     return strpos($member, $wantedString) !== false; 
    } 
} 
0

18 घंटे के बाद मैं initialisation के बिना मेरे नियंत्रण में एक पुस्तकालय में शामिल करने में कामयाब (निर्माता उसकी वजह से समस्या थी, और मैं कर सकता ' मानक कोडिग्निटर $this->load->library() का उपयोग नहीं करें)। https://stackoverflow.com/a/21858556/4701133 का पालन करें। आगे देशी कक्षा प्रारंभिक उपयोग के लिए जागरूक रहें $date = new \DateTime() आगे पीछे-स्लैश के साथ अन्यथा फ़ंक्शन एक त्रुटि उत्पन्न करेगा!