I am looking at using MongoDB with CodeIgniter, however my concern is how data is inserted into the database, most examples take the post values directly into a collection which is a dream because it removes an extract step... however a user could easily inject/overwrite values going into the database, compared to SQL where you would map one-one fields in the database, there appears to be no examples of how one would avoid this type of data injection...
Potentially I see two problems, namely additional values being injected and fields containing incorrect datatypes, ie: a name containing an array or object.
Is the solution to build model classes to map my POST data to along with datatypes or is there an easier method?
EXAMPLE:
MongoDB and CodeIgniter
Looking around I guess the only solution would be to map it into a local array or model class.
An example from: http://www.php.net/manual/en/mongo.tutorial.php
would be more like:
$post = $this->input->post();
$document = array( "title" => (string)$post['title'], "online" => (bool)$post['online']);
$collection->insert($document);
What does everyone think?
CodeIgniter has full active record abilities to help you deal with validation and sanitation of data: http://ellislab.com/codeigniter/user-guide/database/active_record.html
However you can also use something like Doctrine 2: http://docs.doctrine-project.org/en/2.0.x/cookbook/integrating-with-codeigniter.html to sovle this which has a fully fitted MongoDB verfsion of itelf.
Related
Using Yii 1 and ActiveRecord -
I'm pretty new in both.
$types = CasinoSgTypes::model();
$types->findAll();
$types->findByPk(3);
I thought Yii AR will try to search in recently received data first instead of that I've got 2 calls to the database. Probably I'm using it in a wrong way?
sure i can walk through the array of results received by the first query (findAll) manually, but I'd like to do this by means of AR.
in other words is there a way to force AR search inside already received data and only then ask the database or smth like this. how to use AR+Yii models in a right way to avoid unnecessary queries ?
When you call $types->findAll(); the data isn't saved in the AR class and as such you cannot search using it. An easier alternative to searching in the data is to use query caching:
$types->cache(3600)->findByPk(3);
i want to load an entity in my Controller, but dont want that the entity contains all fields. I did that before with the Jms-Serializer, where you can use the Groups Annotations, to avoid loading special fields. But i there you have to serialize your object to json/xml etc.
And i dont want it serialized, i just want that groups function. I searched this site and the internet, but didnt found any solution for my problem.
Hope that someone understand what i mean and got an idea :)
There are a couple of possibilities:
Use partial objects (which will deliver objects where only specified attributes will be filled during hydration): http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/partial-objects.html#partial-objects
This is dangerous and you should be extra careful, because it looks like a fully loaded entity from all perspectives. You have to know why a field is null - just because it's null or because it simply hasn't been filled during hydration.
Don't hydrate objects but query for an array as hydration result (by that again you can specify which array keys you would like to get back): http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#array-hydration
Use this for performance-sensitive queries where you need a lot of read-only data and complex joins. But be aware that you don't have any entities you can manage with Doctrine (e.g. updating, deleting etc.).
Use DTOs which are objects but non-Doctrine-managed entities, there again you can specify what you would like to get hydrated with the NEW syntax: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#new-operator-syntax
Basically the same advise as in 2) but this time you'll get objects. So you can use all your OOP wisdom.
Create your own custom hydration mode - there you can define on your own how entities should be hydrated: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#custom-hydration-modes
Very advanced level. Only useful if you need a special hydration mode for several entities and really no other option delivers at performance and quality as you require it.
You can use partial objects, but you should be careful. For example:
$q = $em->createQuery("select partial u.{id,name,otherField} from MyApp\Entity\User u");
You can read more here: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/partial-objects.html
I have a form that a user will enter their studentID,Name,Major etc. then use those info to fill up 'student' class to create a 'student' object.
Now, I want to store these objects somewhere, somehow, and I want to be able to pull them back to use its data. I've looked into 'object serialization' but not quite sure if this will fulfill my needs, as I don't fully understand how this thing works...any help would be great, thanks.
And, I don't want to create a database, at all. No Mysql is allowed for this little assignment of mine...
You could serialize your object as is and persist it to disk, but what happens if you want to search for students based on some criteria?
Usually, a relational database is used and an ORM to map your PHP objects to a rdbms table
Wikipedia has a list of ORM's and frameworks for PHP, If you want something more lightweight then managin a db server, at least look into Sqlite
Be careful when storing serialize objects. You might loose the ability to do certain things like search records. And if you don't understand how they work then they might behave unexpectedly.
A better approach would be to store individual properties as rows in database tables and then fetch the data into objects. To do this you can use ORMs like Doctrine which will map objects to database tables and persist them. Or a simple database class using PDO should fulfill your basic needs as well.
Ok, so everyone has decided (and for good reason) strait SQL is of the devil. This leaves us with many methods of placing a "middle-man" in our code to separate our code from the database. I am now going to spit out all the info I have gathered in the hope someone can set me strait and tell me what I built.
An ORM (Object-relational mapping) is a series of tools (loosely or tightly integrated depends) which maps database rows to objects in the application.
In an AR (Active-Record) is a type of ORM in which a database table or view is wrapped into a class, thus an object instance is tied to a single row in the table.
Data mapping (DM) is a type of ORM that is the process of creating data element mappings between two distinct data models.
All three claim to work like this:
$user = new User();
$user->name = 'Fred';
$user->save();
Usually with a User class something like this:
class User extends Model {
// Specify the database table
protected $table = "users";
// Define your fields
protected $fields = array(
'id' => array('type' => 'int', 'primary' => true),
'name' => array('type' => 'string', 'required' => true),
'email' => array('type' => 'text', 'required' => true)
);
}
With this setup you can easily fetch rows without the need to write SQL.
// users
$users = $user->fetch(array('id' => 3));
Some AR classes actually look more like this:
$db->where('id' => 3);
$db->join('posts', 'posts.user_id = users.id');
$results = $db->get('users');
Ok, now this is where it gets hairy. Everyone and his brother seems to have a different view on what type of code falls where. While most agree that an AR or DM is a type of ORM - but sometimes the lines that tell AR's from DM's seem to smear.
I wrote a class that uses a single object ($db) in which you make calls to this object and it handles SQL creation for result saving/fetching.
//Fetch the users
$results = $db->select('id, name')->where('id > 4')->get('users');
//Set them active
while($user = $results->fetch()) {
$user->active = TRUE;
$user->save();
}
So the question is "what is it?", and why don't people agree on these terms?
It's not that straight SQL is the devil - sometimes it's pretty much required to write raw SQL to get a query to perform the way you want it to. To me, ORMs are much more about eliminating manual work than anything else (like avoiding SQL at all costs). I just don't want to have to setup all my code objects with all hand-crafted queries for every project. That's just a ridiculous amount of work and thought. Instead, ORM tools provide a nice and automated way to create data objects that would have required a lot of manual work otherwise. Now I can have automatic individual row objects that I can extend and create custom functions for, without thinking about it. I can retrieve related rows from different tables without having to hand-code that query.
It looks like your User class example is from phpDataMapper, and if so, it also has some other built-in niceties like auto table migrations so you don't have to distribute an SQL file for your table structures as well as a few helper functions and other things. All features included intended to save you time - that's the main goal.
The most important distinction between AR and DM is that an ActiveRecord (AR) row knows about it's own data store, and thus has saving/updating functions on each row object - $user->save() - The "record" is "active". With DataMapper (DM), on the other hand, each individual row does NOT know about it's own data store, by definition. The row is more of a dumb value object that can be worked with in your code. The mapper is responsible for translating the changes to that row back to the datastore - $mapper->save($user). That's the most significant difference - you will find most of the core ORM features to be the same in almost any implementation. It's just mostly a matter of how it's put together at the core architectural level.
You might as well make up the acronyms ORM, RM DM whatever ... it is all just state transferred from one medium to another and wrapped in function/semantics.
Sun Microsystems and Microsoft do it all the time with Java and C#. Let's take something simple and give it a new name! What a great idea.
If you say ORM .. everyone knows what it is, in its many guises. Your code looks like the Linq stuff though.
No magic, but alot of buzzwords and fuss IMHO.
Agreed with #Aiden Bell. But I think you are right in pointing out the differences. I use LINQ to SQL which in your definition is simply Active-Record style of ORM. For me this works great as I work on a lot of greenfield apps and start at the db to build out my classes. From there I tend to follow a Domain Driven Design approach (I know...this is a classes first concept) working with my generated classes. To me this gets me down the road quickly.
Having said this I have also worked with Entity Framework and NHybernate. Entity Framework is the UBER data mapper and NHybernate is also a data mapper but without as much complexity! I personally feel that Entity Framework has a long ways to go. If I was ever to need more complexity such as in a brownfield application where the db was fairly set in stone and I needed to get my classes to represent my application rather than my database then I would prefer to move to something more along the lines of NHybernate and its data mapping funcationality.
I think each of these tools has it's place. It is not fair to say that they are all the same as they are not. An active record is great in that it generates classes for me that directly represent my database. This works when I created the database or the database closely represents my ubiquitous terms and concepts of the application. The mapping types of orms work when I have a fixed db that doesn't make sense or clearly map to my application in which case I can encapsulate the complexity or lack there of in my database to create a rich domain via the mapping features of the ORM tool.
Is there a simple way to write a common function for each of the CRUD (create, retreive, update, delete) operations in PHP WITHOUT using any framework. For example I wish to have a single create function that takes the table name and field names as parameters and inserts data into a mySQL database. Another requirement is that the function should be able to support joins I.e. it should be able to insert data into multiple tables if required.
I know that these tasks could be done by using a framework but because of various reasons - too lengthy to explain here - I cannot use them.
If you try to write such function you'll soon discover that you've just realized yet another framework.
Of course not, that's why those frameworks exist and implement crud facilities. I'd first try to convince whomever it takes to actually use an existing framework and second, failing the above, I'd take a look at one or two of them and copy the implementation ideas. Failing all that you could take a look at http://www.phpobjectgenerator.com/
Without any frameworks includes without any ORMs? Otherwise I would suggest to have a look at Doctrine or Propel.
I know the way you feel.
Pork.DbObject is a simple class that you can extend your objects from. It just needs a db connection class to work.
please check out:
www.schizofreend.nl/pork.dbobject/
(oh yeah, yuk # php object generator. bloat alert! who wants to have those custom functions in every class???)
I came across this question on SO a while back and I ended up not finding anything at that time that did this in a light-weight fashion.
I ended up writing my own and I recently got around to open sourcing it (MIT license) in case others may find it useful. It's up on Github, feel free to check it out and use it if it fits your needs!
https://github.com/ArthurD/php-crud-model-class
Hopefully it will find some use - would love to see some improvements / contributions, too so feel free to submit pull requests! :-)
I wrote this very thing, it's kind of a polished scaffold. It's basically a class the constructor of which takes the table to be used, an array containing field names and types, and an action. Based on this action the object calls a method on itself. For example:
This is the array I pass:
$data = array(array('name' => 'id', 'type' => 'hidden')
, array('name' => 'student', 'type' => 'text', 'title' => 'Student'));
Then I call the constructor:
new MyScaffold($table, 'edit', $data, $_GET['id']);
In the above case the constructor calls the 'edit' method which presents a form displaying data from the $table, but only fields I set up in my array. The record it uses is determined by the $_GET method. In this example the 'student' field is presented as a text-box (hence the 'text' type). The 'title' is simply the label used. Being 'hidden' the ID field is not shown for editing but is available to the program for use.
If I had passed 'delete' instead of 'edit' it would delete the record from the GET variable. If I passed only a table name it would default to a list of records with buttons for edit, delete, and new.
It's just one class that contains all the CRUD with lots of customisability. You can make it as complicated or as simple as you wish. By making it a generic class I can drop it in to any project and just pass instructions, table information and configuration information. I might for one table not want to permit new records from being added through the scaffold, in this case I might set "newbutton" to be false in my parameters array.
It's not a framework in the conventional sense. Just a standalone class that handles everything internally. There are some drawbacks to this. The key ones must be that all my tables must have a primary key called 'id', you could get away without this but it would complicate matters. Another being that a large array detailing information about each table to be managed must be prepared, but you need only do this once.
For a tutorial on this idea see here
I think you should write your own functions that achieve CRUD unless you are stressed for time. it might be a framework on it's own but you need to learn what the framework does before screaming framework....it also becomes handy to know these things because you can easily pickup bugs on the framework and fix them your self........
it is possible but I wouldn't recommend it.
If there's absolutely NO way to use a framework you could create a base class that all other model objects extend. You can then make the base class generate & execute SQL based on get_class() and get_class_vars().
Is it possible? Yes.
Would I recommend it? nope