Database approch in YII - php

I am developing my first YII website. I have a couple of doubts about YII database.
There are three methods to query database in yii.
Database Access Objects
Query Builder
Active Record
Out of these three methods which is the secure and most preferred method?
If I have custom queries to perform which method should I prefer?
In case of Query Builder queries we explicitly choose table like
$user = Yii::app()->db->createCommand()
->select('id, username, profile')
->from('tbl_user') // explicitly choosing the table
->join('tbl_profile p', 'u.id=p.user_id')
->where('id=:id', array(':id'=>$id))
->queryRow();
so where should I write query builder queries? Is there any advantage if I write them in corresponding table model?
If I use DAO or query builder what class should extend my model?
How to validate user inputs if I follow DAO method or query builder method?

Depends. All are equally secured if you know how to use them securely.
DAO. That's my opinion though.
In the models.
There are two main model classes in Yii. CFormModel and CModel. For queries, extend the class with respect to CModel.
Just a note at the end. DAO is the fastest among them. Active record is slowest. On the other hand, active record is more convenient. You are the one who needs to decide what should be the balance.

You can use CActiveRecord for all your requirements.

Related

CodeIgniter 4 Model and the Query Builder class for complex queries

Which is the best method to use for the CodeIgniter 4 among the Model and the Query Builder class? What are the limitations of the CodeIgniter 4 Model and the Query Builder?
I searched a lot about this question. But I did not get any clear answer. For complex queries currently, I am using the Query Builder class. But I want to know what is the best method among the CodeIgniter 4 Model and the Query Builder class. Your answers are highly appreciated.
It depends on your needs and preferences.
Model class - This is used by extending the base Model class, and you can add your own functions/methods. It is not as flexible as the Query Builder, and it only has pre-defined methods.
Query Builder - Easy to build complex queries. But more room for errors if didn't handle it. Ex SQL injection if you failed to validate it properly.

Where do SQL queries belong in a MVC project?

I have read a book about MVC last week and a general one about design patterns, but I'm still confused as to where SQL queries belong in my code: the model or in the controller?
Let's take a very simple example, where you have a /popular page that will print the 5 most popular stories on a website.
In your model, you would have a class for prepared staments, and a class for assisting in the creation of the SELECT query. In your view, you'd have the HTML elements that display the /popular page.
Where does the query "SELECT most popular stories LIMIT 5" belong to? Is that something a controller class should ask, taking query methods from the model and passing to the view, or should the query be declared instead on a model class related to the /popular page?
Is the distinction even relevant? Would placing that query on the controller or the model be both considered professional ways to build a MVC?
Thank you. It seems most people get stuck understanding what to place on controllers
Edit: thanks for help everyone. Unfortunately as a new account I can't upvote any helpful posts yet
Usually (based on my experiences with MVC frameworks) the model layer takes care of database-related stuff in MVC.
Consider following approach:
Create abstract class which covers all the DB operations (selects, updates, etc). Each table would be a PHP class extending such class. You can then define DB table name in for instance private field, constructor or depending on model name.
Each controller (or the single controller) would load desired model, and use its methods to fetch data as associative arrays or objects, delete the data, change it.
After all DB operations have been done, controller returns view and passes data as its parameters.
Note that models are great place to put all the validation rules, and some helper methods due to the fact that they can be easily tested in PHPUnit.

Should I be making this a model?

I have a family of complex select queries which I need to call from different parts of the application. I think I should group them all into a model class, but would like to verify this.
The queries all work off the same set of 5 tables. Each of these tables has its own Table Data Gateway class and Row Data Gateway class, but my new class for the queries would not be implementing any such pattern (since it doesn't wrap a table or row). My new class would be calling on the Table and Row Data Gateways already established.
In addition, the values that come from users can't be susbstituted into the queries directly, so I plan to do some pre-processing in the new class as well. This pre-processing includes accessing the DB for lookup values, etc.
Does this sound fair? I think it's exactly how models should be used, but I can be spectacularly wrong about such things so would appreciate any comments or advice. (FYI, I'm using Zend Framework).
Queries don't go in the Model part. They are persistence related (the model doesn't handle persistence).
These complex queries should be in the Persistence layer, which is here the Table Data Gateway classes.
I would name the Table Data Gateway classes "DAO" (Data Access Object). A Table Data Gateway is a kind of DAO, since you can have a DAO that help you get things from files, webservices...
So you can keep your actual classes, and add a DAO to manage these complex queries. This DAO is not providing you access to a specific DB table, but it is still providing you access to a data source (composed by several DB tables).
Edit :
I suggest you to create a DAO interface (it may be empty). You DB Tables will implement this interface. Your new class will also implement this interface, but not extend Zend_Db_Table.
In short, you are redefining/renaming your persistence layer, from "Zend Db Table" to "DAO" (which makes it more generic). Zend Db Table is a kind of DAO.

Zend DB Table ? Or SQL by your own?

how do you handle middle sized projects with PHP and Zend Framework. Do you use Zend DB Table / Row for your Models and Database operations ? Or do you have some kind of Abstract Model class with your SQL Statements ?
I would like to hear some opinions, thanks.
I'd recommend Zend_Db_Table and Row for basic handling of database stuff. It's not very advanced (see Doctrine for a full ORM) but is a good way to encapsulate functionality and you can add custom functionality to Row objects.
You can always add raw SQL methods to your models:
class MyModel extends Zend_Db_Table_Abstract {
public function getSomething(){
return $this->getAdapter()->fetchAll("SELECT * FROM `tbl`");
}
}
We personally use Zend_Db_Select() in models in our company. It's because we use many joins and stuff in our ecommerce software. For simple apps is Zend_Db_Table suitable.
I've been using Doctrine lately for the DB layer and haven't looked back. I found it simple to populate object graphs from the DB. Other solutions were too cumbersome in dealing with relationships for my liking.
My domain model sits above the DB layer and manages the business logic.
It really depends on your domain model though. The current version of Doctrine requires all models to extend a class, so it's not suitable if you need model inheritance. Also, it's only suitable if your model is similar to your DB structure.

What do you think of returning select object instead of statement result?

I would have liked to know if it was a good idea to return a select object from a method like '$selectObj = getSomethingByName($name)' to then pass it to another method like 'getResult($selectObj)' which will do the trick.
The idea is to be able to pass the select object to any usefull function like 'setLimit(10)' or addCriteria('blabla') depending on my model...
But is it a good idea to do this ? it could be 'unsecure' because user will be able to modify the object himself, and i should not want to this..
I used to do simple method before like above but returning the result as a row... but it's sometimes painfull when you have complex statement depending on different tables..
The problem you are facing (complex statements depending on different tables) is an old and widespread problem with ORM frameworks in general. There are lots of things SQL can do, that an ORM doesn't do very well. Inevitably, you have to make up the different in complexity by writing lots of complicated code in your Controller or your View.
Instead, use a Domain Model pattern and encapsulate the complex multi-table database logic into one place, so your Controllers and Views don't have to know about all the sundry details. They just know about the interface of your Domain Model class, and that class has the sole responsibility to know how to fetch the information from the database.
Remember: a Model "HAS-A" table (or multiple tables) -- instead of Model "IS-A" table.

Categories