Nội dung
- shares
- Facebook Messenger
- Gmail
- Viber
- Skype
Lập trình CSDL bằng Doctrine ORM với Codeigniter.
Trong blog mình đã có một vài bài hướng dẫn cơ bản về codeigniter. Codeigniter có thư viện tiềm năng cho chúng ta làm việc với CSDL/database. Bên cạnh active record class bạn có thể sử dụng với các câu lệnh SQL phổ thông. Tuy nhiên, hỗ trợ database trong codeigniter là chưa đủ, đặc biệt nhiều developer thích chuyển sang làm việc với ORM cho database nhưng Codeigniter mặc định không được tích hợp sẵn. Tuy nhiên, doctrine là một ORM đầy sức mạnh trong PHP và nó dễ dàng tích hợp và sử dụng doctrine trong Codeigniter.
Bạn có thể xem chi tiết tài liệu doctrine ở trang chính thức này. Tuy nhiên, bạn có thể gặp một số vấn đề trở ngại và khó hiểu vì tài liệu viết không rõ ràng đặc biệt cho những người mới bắt đầu. Do đó mình viết bài này sẽ giải thích cho các bạn hiểu cách thuật ngữ và cách tích hợp doctrine với Codeigniter. Ở đây cũng đưa ra các ví dụ về PHO mà bạn cần học. Nếu cần bạn có thể đọc qua hướng dẫn bắt đầu với doctrine.
Download và cài đặt
Đầu tiên, chúng ta tải doctrine orm phiên bản mới nhất. Sau đó tiến hành giải nén thư mục ‘doctrine’ vào thư mục ‘third_party’ của Codeigniter.
nếu bạn quen dùng composer và đã biết cách sử dụng composer với codeigniter, bạn có thể cài đặt doctrine orm bằng cách khai báo vào composer.json như dưới đây:
"require": { "doctrine/orm": "dev-master" }
Bây giờ, tại folder ‘application/libraries’, tạo file class mới tên “doctrine.php” nó sẽ chứa tất cả những cài đặt cần thiết của thư viện doctrine cho trang web codeigniter của chúng ta. Chép vào nội dung sau:
use Doctrine\Common\ClassLoader, Doctrine\ORM\Configuration, Doctrine\ORM\EntityManager, Doctrine\Common\Cache\ArrayCache, Doctrine\DBAL\Logging\EchoSQLLogger, Doctrine\ORM\Mapping\Driver\DatabaseDriver, Doctrine\ORM\Tools\DisconnectedClassMetadataFactory, Doctrine\ORM\Tools\EntityGenerator; /** * CodeIgniter Smarty Class * * initializes basic doctrine settings and act as doctrine object * * @final Doctrine * @category Libraries * @author Md. Ali Ahsan Rana * @link http://codesamplez.com/ */ class Doctrine { /** * @var EntityManager $em */ public $em = null; /** * constructor */ public function __construct() { // load database configuration from CodeIgniter require APPPATH.'config/database.php'; // Set up class loading. You could use different autoloaders, provided by your favorite framework, // if you want to. require_once APPPATH.'third_party/Doctrine/Common/ClassLoader.php'; $doctrineClassLoader = new ClassLoader('Doctrine', APPPATH.'third_party'); $doctrineClassLoader->register(); $entitiesClassLoader = new ClassLoader('models', rtrim(APPPATH, "/" )); $entitiesClassLoader->register(); $proxiesClassLoader = new ClassLoader('proxies', APPPATH.'models'); $proxiesClassLoader->register(); // Set up caches $config = new Configuration; $cache = new ArrayCache; $config->setMetadataCacheImpl($cache); $driverImpl = $config->newDefaultAnnotationDriver(array(APPPATH.'models/Entities')); $config->setMetadataDriverImpl($driverImpl); $config->setQueryCacheImpl($cache); // Proxy configuration $config->setProxyDir(APPPATH.'models/proxies'); $config->setProxyNamespace('Proxies'); // Set up logger //$logger = new EchoSQLLogger; //$config->setSQLLogger($logger); $config->setAutoGenerateProxyClasses( TRUE ); // Database connection information $connectionOptions = array( 'driver' => 'pdo_mysql', 'user' => $db['default']['username'], 'password' => $db['default']['password'], 'host' => $db['default']['hostname'], 'dbname' => $db['default']['database'] ); // Create EntityManager $this->em = EntityManager::create($connectionOptions, $config); } }
Chú ý: đoạn code trên yêu cầu PHP 5.3.x và hầu hết giống với tài liệu cung cấp bởi doctrine nhưng mình đã giam tải để phù hợp với phiên bản codeigniter 2.x. Bạn cũng sẽ cần tạo 2 folders trong thư mục ‘application/models’ với tên ‘proxies’ và ‘entities’. Quay lại code trên, đầu tiên chúng ta load cấu hình database của codeigniter và doctrine class sẽ nạp các lớp cần thiết cùng với những thành phần khác.
Để biết chi tiết về các thông tin cấu hình và chúng làm việc như thế nào,vui lòng xem tại đây.
Mặc dù, có thể tạo entity class từ file YAML/database thông qua giao diện lệnh, và nó cũng có thể đơn giản hơn bằng cách dùng mã PHP để sinh ra class mà không cần dùng thêm bất cứ cái gì. Chúng ta sẽ viết thêm một hàm cần để tạo ra entity classes. Hãy đặt nó vào class trước đó và gọi hàm này ở dòng cuối cùng trong phương thức constructor.
/** * generate entity objects automatically from mysql db tables * @return none */ function generate_classes(){ $this->em->getConfiguration() ->setMetadataDriverImpl( new DatabaseDriver( $this->em->getConnection()->getSchemaManager() ) ); $cmf = new DisconnectedClassMetadataFactory(); $cmf->setEntityManager($this->em); $metadata = $cmf->getAllMetadata(); $generator = new EntityGenerator(); $generator->setUpdateEntityIfExists(true); $generator->setGenerateStubMethods(true); $generator->setGenerateAnnotations(true); $generator->generate($metadata, APPPATH."models/Entities"); }
Nhớ rằng, gọi phương thức ‘generate_classes’ chỉ một lần duy nhất sau khi entity classes được sinh ra, sau đó xóa dòng gọi phương thức này hoặc để ký hiệu comment nếu không bạn sẽ gặp lỗi.
Nếu đôi khi thay đổi cấu trúc database (thêm, xóa table) mà lỡ xóa thư mục ‘entities’ thì chúng ta kích hoạt lại hàm trên và gọi một lần duy nhất.
Cơ bản sử dụng Doctrine với Codeigniter
Ví dụ tạo contact form đơn giản trong codeigniter bằng cách sử dụng doctrine ORM trong codeigniter.
Tạo bảng MySQL database ‘pd_contact’ giống như sau:
Doctrine sẽ tương ứng sinh ra entity class giống thế này:
<?php /** * PdContact * * @Table(name="pd_contact") * @Entity */ class PdContact { /** * @var integer $id * * @Column(name="id", type="integer", nullable=false) * @Id * @GeneratedValue(strategy="IDENTITY") */ private $id; /** * @var string $name * * @Column(name="name", type="string", length=50, nullable=false) */ private $name; /** * @var string $email * * @Column(name="email", type="string", length=50, nullable=false) */ private $email; /** * @var string $subject * * @Column(name="subject", type="string", length=100, nullable=false) */ private $subject; /** * @var text $message * * @Column(name="message", type="text", nullable=false) */ private $message; /** * Get id * * @return integer $id */ public function getId() { return $this->id; } /** * Set name * * @param string $name */ public function setName($name) { $this->name = $name; } /** * Get name * * @return string $name */ public function getName() { return $this->name; } /** * Set email * * @param string $email */ public function setEmail($email) { $this->email = $email; } /** * Get email * * @return string $email */ public function getEmail() { return $this->email; } /** * Set subject * * @param string $subject */ public function setSubject($subject) { $this->subject = $subject; } /** * Get subject * * @return string $subject */ public function getSubject() { return $this->subject; } /** * Set message * * @param text $message */ public function setMessage($message) { $this->message = $message; } /** * Get message * * @return text $message */ public function getMessage() { return $this->message; } }
Tiếp đến, phần tạo model nơi chứa chứa những phương thức sử lý database vd chèn dữ liệu vào table khi nhấn nút submit trên contact form.
require_once(APPPATH."models/Entities/PdContact.php"); use \PdContact; /** * manipulates data and contains data access logics for Enity 'User' * * @final Homemodel * @category models * @author Md. Ali Ahsan Rana * @link http://codesamplez.com */ class Homemodel extends CI_Model { /** * @var \Doctrine\ORM\EntityManager $em */ var $em; public function __construct() { parent::__construct(); $this->em = $this->doctrine->em; } /** * Add contact messages to database * @param array $contact_form * @return bool */ function add_message() { /** * @var PdContact $contact */ $contact = new PdContact(); $contact->setName($this->input->post("name"); $contact->setEmail($this->input->post("email"); $contact->setSubject($this->input->post("subject"); $contact->setMessage($this->input->post("message"); try { //save to database $this->em->persist($contact); $this->em->flush(); } catch(Exception $err){ die($err->getMessage()); } return true; } }
Ví dụ trên sẽ chèn thêm dòng mới vào bảng ‘pd_contact’ với dữ liệu posted form. Query sẽ thực thi khi gọi lệnh $this->em->flush();
. Nếu có nhiều lệnh tương tác vào database mình khuyến cáo cách tốt nhất là gộp chúng vào một ứng dụng batch, hiệu xuất làm việc sẽ nhanh hơn là cách thực thi query truyền thống.
Sử dụng Doctrine Command Line trong Codeigniter
Nếu bạn thường xuyên dùng CLI tool, bạn sẽ thấy thích thú vì doctrine có hỗ trợ command line. Để làm điều này, bạn sẽ tạo file “cli-config.php” trong thư mục hiện tại và chép vào đoạn code sau đây:
$system_path = 'system'; $application_folder = 'application'; define('BASEPATH', str_replace("\\", "/", $system_path)); define('APPPATH', $application_folder.'/'); include __DIR__."/vendor/autoload.php"; include __DIR__."/application/libraries/doctrine.php"; $doctrine = new Doctrine(); $em = $doctrine->em; $helperSet = new \Symfony\Component\Console\Helper\HelperSet(array( 'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()), 'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em) )); return $helperSet;
Bây giờ, chúng ta có thể sử dụng công cụ command line này rồi. Kiểm tra toàn bộ path nếu OK, chạy ‘{path}/{to}/{cli}/doctrine’ và bạn sẽ nhìn thấy giao diện giống như hình này:
Ví dụ khác:
$./vendor/bin/doctrine orm:validate-schema $./vendor/bin/doctrine orm:generate:proxies ....
Chú ý rằng, ở đây mình giả định bạn đang sử dụng composer cài đặt cho doctrine. Nếu không, path của doctrine là ‘./vendor/bin/doctrine’.
Kết luận
Hi vọng bài viết hướng dẫn sử dụng doctrine với Codeigniter này sẽ hữu ích cho những ai đang tìm hiểu và quyết định dùng doctrine. Chúc bạn thành công!
Nếu bạn thích bài viết này, hãy ủng hộ chúng tôi bằng cách đăng ký nhận bài viết mới ở bên dưới và đừng quên chia sẻ kiến thức này với bạn bè của bạn nhé. Bạn cũng có thể theo dõi blog này trên Twitter và Facebook
- shares
- Facebook Messenger
- Gmail
- Viber
- Skype