Title doesn't make too much sense, but I will try to explain further.
I am currently making a website (a game), and I currently have different folders for users/ranks etc, each with their own config and class.****.php file.
I am new to PHP/MySQL and now it seems like having these functions seperately with their own config.php to connect to the database is not the greatest idea.
If I want to fetch, let's say, username and rank, then I could be object-oriented and have a getter for those in each class.****.php file, or I could fetch it inside the file required. However, that's gonna be a lot of "SELECT FROM" in each file, which seems pretty unecessary.
Is there a different approach that I haven't thought about, or should I have all the functions in one file?
Feel free to ask questions if I am too vague.
Thanks in advance.
You might want to look at ORM frameworks. How do they work?
You fetch data in an OO way and get "entities"-rows which you can manipulate with your own functions. In some cases you may never have to write SQL. Here are some examples:
General purpose /Light-weight/Simple:
RedBeanPHP
IdiORM
Advanced/Full-fledged/Feature-rich
Eloquent
Doctrine
The list is endless. Just try each one of those and see what works for you
Related
OOP principles were difficult for me to grasp because for some reason I could never apply them to web development. As I developed more and more projects I started understanding how some parts of my code could use certain design patterns to make them easier to read, reuse, and maintain so I started to use it more and more.
The one thing I still can't quite comprehend is why I should abstract my data layer. Basically if I need to print a list of items stored in my DB to the browser I do something along the lines of:
$sql = 'SELECT * FROM table WHERE type = "type1"';'
$result = mysql_query($sql);
while($row = mysql_fetch_assoc($result))
{
echo '<li>'.$row['name'].'</li>';
}
I'm reading all these How-Tos or articles preaching about the greatness of PDO but I don't understand why. I don't seem to be saving any LoCs and I don't see how it would be more reusable because all the functions that I call above just seem to be encapsulated in a class but do the exact same thing. The only advantage I'm seeing to PDO are prepared statements.
I'm not saying data abstraction is a bad thing, I'm asking these questions because I'm trying to design my current classes correctly and they need to connect to a DB so I figured I'd do this the right way. Maybe I'm just reading bad articles on the subject :)
I would really appreciate any advice, links, or concrete real-life examples on the subject!
Think of a abstracting the data layer as a way to save time in the future.
Using your example. Let's say you changed the names of the tables. You would have to go to each file where you have a SQL using that table and edit it. In the best case, it was a matter of search and replace of N files. You could have saved a lot of time and minimized the error if you only had to edit one file, the file that had all your sql methods.
The same applies to column names.
And this is only considering the case where you rename stuff. It is also quite possible to change database systems completely. Your SQL might not be compatible between Sqlite and MySQL, for example. You would have to go and edit, once again, a lot of files.
Abstraction allows you to decouple one part from the other. In this case, you can make changes to the database part without affecting the view part.
For very small projects this might be more trouble than it is worth. And even then, you should still do it, at least to get used to it.
I'm NOT a php person but this is a more general question so here goes.
You're probably building something small, sometimes though even something small/medium should have an abstracted data layer so it can grow better.
The point is to cope with CHANGE
Think about this, you have a small social networking website. Think about the data you'll store, profile details, pictures, friends, messages. For each of these you'll have pages like pictures.php?&uid=xxx.
You'll then have a little piece of SQL slapped in there with the mysql code. Now think of how easy/difficult it would be to change this? You would change 5-10 pages? When you'll do this, you'll probably get it wrong a few times before you test it thoroughly.
Now, think of Facebook. Think of the amount of pages there will be, do you think it'll be easier to change a line of SQL in each page!?
When you abstract the data access correctly:
Its in one place, its easier to change.
Therefore its easier to test.
Its easier to replace. (Think about what you'd have to do if you had to switch to another Database)
Hope this Helps
One of the other advantage of abstracting the data layer is to be less dependent on the underlying database.
With your method, the day you want to use something else than mysql or your column naming change or the php API concerning mysql change, you will have to rewrite a lot of code.
If all the database access part was neatly abstracted, the needed changes will be minimal and restricted to a few files instead of the whole project.
It is also a lot easier to reuse code concerning sql injection or others utility function if the code is centralized in one place.
Finally, it's easier to do unit testing if everything goes trough some classes than on every pages from your project.
For example, in a recent project of mine (sorry, no code sharing is possible), mysql related functions are only called in one class. Everything from query generation to object instantiation is done here. So it's very for me to change to another database or reuse this class somewhere else.
In my opinion, the data access is one of the most important aspects to separate / abstract out from the rest of your code.
Separating out various 'layers' has several advantages.
1) It neatly organises your code base. If you have to make a change, you'll know immediately where the change needs to be made and where to find the code. This might not be so much of a big deal if you're working on a project on your own but with a larger team the benefits can quickly become obvious. This point is actually pretty trivial but I added it anyway. The real reason is number 2..
2) You should try to separate things that might need to change independently of each other. In your specific example, it is conceivable that you would want to change the DB / data access logic without impacting the user interface. Or, you might want to change the user interface without impacting on the data access. Im sure you can see how this is made impossible if the code is mixed in with each other.
When your data access layer, has a tightly defined interface, you can change its inner workings however you want, and as long as it still adheres to the interface you can be pretty certain it wont have broken anything further up. Obviously this would still need verifying with testing.
3) Reuse. Writing data access code can get pretty repetitive. It's even more repetitive when you have to rewrite the data access code for each page you write. Whenever you notice something repetitive in code, alarm bells should be ringing. Repetitiveness, is prone to errors and causes a maintenance problem.
I'm sure you see the same queries popping up in various different pages? This can be resolved by putting those queries lower down in your data layer. Doing so helps to ease maintenance; whenever a table or column name changes, you only need to correct the one place in your data layer that references it instead of trawling through your entire user interface and potentially missing something.
4) Testing. If you want to use automated tool to carry out unit testing you will need everything nicely separated. How will you test your code to select all Customer records when this code is scattered all throughout your interface? It is much easier when you have a specific SelectAllCustomers function on a data access object. You can test this once here and be sure that it will work for every page that uses it.
There are more reasons that I'll let other people add. The main thing to take away is that separating out layers allows one layer to change without letting the change ripple through to other layers. As the database and user interface are areas of an application / website that change the most frequently it is a very good idea to keep them separate and nicely isolated from everything else and each other.
In my point of view to print just a list of items in a database table, your snippet is the more appropriate: fast, simple and clear.
I think a bit more abstraction could be helpful in other cases to avoid code repetitions with all the related advantages.
Consider a simple CMS with authors, articles, tags and a cross reference table for articles and tags.
In your homepage your simple query will become a more complex one. You will join articles and users, then you will fetch related tag for each article joining the tags table with the cross reference one and filtering by article_id.
You will repeat this query with some small changes in the author profile and in the tag search results.
Using a abstraction tool like this, you can define your relations once and use a more concise syntax like:
// Home page
$articles = $db->getTable('Article')->join('Author a')
->addSelect('a.name AS author_name');
$first_article_tags = $articles[0]->getRelated('Tag');
// Author profile
$articles = $db->getTable('Article')->join('Author a')
->addSelect('a.name AS author_name')->where('a.id = ?', $_GET['id']);
// Tag search results
$articles = $db->getTable('Article')->join('Author a')
->addSelect('a.name AS author_name')
->join('Tag')->where('Tag.slug = ?', $_GET['slug']);
You can reduce the remaining code repetition encapsulating it in Models and refactoring the code above:
// Home page
$articles = Author::getArticles();
$first_article_tags = $articles[0]->getRelated('Tag');
// Author profile
$articles = Author::getArticles()->where('a.id = ?', $_GET['id']);
// Tag search results
$articles = Author::getArticles()
->join('Tag')->where('Tag.slug = ?', $_GET['slug']);
There are other good reasons to abstract more or less, with its pros and cons. But in my opinion for a big part the web projects the main is this one :P
Currently I am working with a commercial project with PHP. I think this question not really apply to PHP for all programming language, just want to discuss how your guys solve it.
I work in MVC framework (CodeIgniter).
all the database transaction code in model class.
Previously, I seperate different search criteria with different function name.
Just an example
function get_student_detail_by_ID($id){}
function get_student_detail_by_name($name){}
as you can see the function actually can merge to one, just add a parameter for it. But something you are rushing with project, you won't look back previously got what similar function just make some changes can meet the goal. In this case, we found that there is a lot function there and hard to maintenance.
Recently, we try to group the entity to one ultimate search
something like this
function get_ResList($is_row_count=FALSE, $record_start=0, $arr_search_criteria='', $paging_limit=20, $orderby='name', $sortdir='ASC')
we try to make this function to fit all the searching criteria. However, our system getting bigger and bigger, the search criteria not more 1-2 tables. It require join with other table with different purpose.
What we had done is using IF ELSE,
if(bla bla bla)
{
$sql_join = JOIN_SOME_TABLE;
$sql_where = CONDITION;
}
at the end, we found that very hard to maintance the function. it is very hard to debug as well.
I would like to ask your opinion, what is the commercial solution they solve this kind of issue, how to define a function and how to revise it. I think this is link project management skill. Hope you willing to share with us.
Thanks.
If you're using codeigniter, just use:
http://www.overzealous.com/dmz/
I don't know what I even used to do without it.
Congratulations, you have invented an ORM :)
There are plenty of commercial ORM solutions but, in my opinion, all they no better than yours. And I'd go for good ol' SQL.
After I did some research on ORM vs Active Record. For my situation I didn't find a lot of help by switching to ORM will help me better.
I found out that ORM is not do very in READ data. But good in Create, Update, and Delete.
My current solution is every model recompile the my own OR_WHERE() / AND_WHERE(), before pass to the $this->db->query(). It is more easy to maintain and customize.
I have a large system that I have coded and I wish to make the code (dare I say) more simple and easy to read. Unfortunately before this, I haven't used functions much.
I have many different MySQL Queries that are run in my code, I feel that if I make the various displays into functions and store them in a separate file it would make the code much easier to maintain (actually, I know it would).
The only thing I am wondering is, if this is a common practice and if you think that it is going to hurt me in the long run in terms of performance and other factors. Here is an example of what I currently am using:
$result = mysql_query("SELECT * FROM table");
while($row = mysql_fetch_array($result)){
/* Display code will go here */
}
As you can imagine this can get lengthy. I am thinking of making a function that will take the result variable, and accomplish this, and then return the results, as so:
$result = mysql_query("SELECT * FROM table");
dsiplayinfo($result);
Do you think this is the right way to go?
[Edit]
The functions would be very different because each of them needs to display the data in different ways. There are different fields of the database that need to be shown in each scenario. Do you feel that this approach is still a good one even with that factor? AKA Modular design is not being fully accomplished, but easy maintenance is.
One thing you want to keep in mind is the principle of DRY: Don't Repeat Yourself.
If you are finding there is a block of code that you are using multiple times, or is very similar that can be made the same, then it is a ideal candidate for being moved into a function.
Using more functions can be helpful, and it can be hurtful. In theory it moves you more towards modular design, meaning you can use a function over and over in multiple apps without having to re-write it.
I would honestly encourage you to more toward larger conventions, like the MVC Frameworks out there. Kohana is a great one. It uses things like Helpers for additional outside functionality, Models to query the database, and Controllers to perform all of your logic - and the end-result is passed on to the View to be formatted with HTML/CSS and spiced up with Javascript.
Don't use "SELECT *" -- enumerate the fields you want for performance reasons, as well as maintainence reasons.
In your example, the display code will likely be pretty closely coupled with the SQL query, so you may as well encapsulate them both together
You might consider some sort of MVC framework with an ORM (like CakePHP) which will facilitate Model reuse much better than writing a bunch of functions
You are on the right track! Write your code, then refactor it to make it better--very smart.
Yes, also consider looking into an ORM or some database agnostic interface. This might help reduce duplication as well (and certainly make porting to a new DB easier, should that ever come up).
Basically any time you see similar looking code (be it in structure or in functionality) you have an opportunity to factor it out into functions that can be shared across the application. A good rule of thumb is Don't Repeat Yourself (DRY)
Can someone please explain "re-usable structures" for me?
I was working on making some db objects in php, but was told I was using too much processing from the computer cause I made stuff to complicated with the below objects:
My DB objects:
$db = new Database;
$db->db_connect();
$post_content = new DbSelect;
$post_content->select('id', 'title', 'firstName', 'created', 'catName', 'tagName');
$post_content->from('content');
$post_content->join('inner');
$post_content->on('category','cat_id','id');
$post_content->where('id','1');
$post_content->order('created');
$db->db_close();
Normal PHP:
mysql_connect();
mysql_db_select();
$query = 'SELECT id, title, s_name, created, cat_name, tag_name
FROM content
JOIN INNER category, cat_id, id
WHERE id=1
ORDER created';
mysql_close();
So to reiterate my questions:
1. A quick explanation of re-usable structures?
2. why is the first method using objects "wrong"?
please note:
I'll be googling this as well as hoping for feedback
I know there a "tools" like Zend and other's that have plenty of db objects built into them, but I'm trying a DIY approach
Don't confuse object-oriented-programmed with "class-oriented" or "object-based" programming. They both, on the surface, can look like OOP but are not.
These are when you take structured code and wrap in a bunch of classes, but don't change the fundamentals of how it operates. When you program with objects in mind, but don't leverage any of the special conventions that OOP affords you (polymorphism, aggregation, encapsulation, etc). This is not OOP.
What you may have here is some of this type of code. It's a little hard to tell. Is the purpose of your DbSelect class to abstract away the raw SQL code, so that you can use connect to any database without having to rewrite your queries? (as many DBAL solutions are wont to do) Or are you doing it "just because" in an effort to look like you've achieved OOP because you turned a basic SQL query into a chain of method calls? If the latter is closer to your motivation for creating this set of classes, you probably need to think about why you're making these classes and objects in the first place.
I should note that, from what I can tell by your simple snippet, you actually have not gained anything here in the way of re-usability. Now, your design may include code that gives flexibility where I cannot see it, but kind of suspect that it isn't there. The procedural/structured snippet is really no more or less reusable than your proposed class-based one.
Whomever you were talking to has a point - developing a complex (or even simple) OOP solution can definitely have many benefits - but to do so without regard to the cost of those benefits (and there's always a cost) is foolish at best, and hazardous at worst.
I'm not sure where to start on this one. Object Oriented design is not a trivial subject, and there are many ways it can go wrong.
Essentially, you want to try to make logical indepedent objects in your application such that you can swap them out for other modules with the same interface, or reuse them in future projects. In your database example, look at PEAR::MDB2. PEAR::MDB2 abstracts the database drivers away from your application so that you don't need to worry about which specific database you're using. Today, you might be using MySQL to run your site. Tomorrow, you might switch to Postgresql. Ideally, if you use a proper OO design, you shoudn't need to change any of your code to make it work. You only need to swap out the database layer for another. (Pear::MDB2 makes this as simple as changing your db connect string)
May I suggest reading Code Complete by Steve McConnell. There's a whole chapter on Classes. While the examples are primarily C++, the concepts can be applied to any programming language, including PHP.
It seems that your solution involves more typing to achieve the same thing as the "normal" way. The string SQL would be more efficient than allocating memory for your object.
You should check out the Active Record pattern if you want to create a data abstraction layer with more features than just a select.
If you are using DbSelect objects to build queries from complicated Forms, then you are doing the right thing.
Query Object pattern
I am wondering what the best way is using php to obtain a list of all the rows in the database, and when clicking on a row show the information in more detail, such as a related image etc.
Should I use frames to do this? Are there good examples of this somewhere?
Edit:
I need much simpler instructions, as I am not a programmer and am just starting out. Can any links or examples be recommended?
Contrary to other's recommendations, I would not recommend a framework or abstraction level. It will insulate you from understanding how php works and requires that you learn php and the framework structure/process at the same time. An abstraction layer is good practice in a commercial environment, but from the vibe of your question, you don't anticipate moving servers or migrating your db.
I recommend working procedurally (not object-oriented) with the php and mysql until you understand what is going on and how the language works.
To respond to your actual question:
You need to connect to the database: mysql_connect()
You need to select the database you want to work with: mysql_select_db()
You need to define the query: msyql_query()
You need to use a while loop to get the data:
$query=mysql_query("select * from table_name");
while($row=mysql_fetch_assoc($query)){
extract($row);
echo $name of field 1.": ".$name of field 2;
}
To make each row of output a link to more info rewrite the echo statement like this:
echo "<a href=\"http://addresstomoreinfo.php?image_id=".$image_id.\">".$name
of field 1.": ".$name of field 2."</a>";
The "name of field" variables represent the column names of your db table and I have made up the layout of the field name, colon, and second field name. How the info is displayed is up to you.
The question mark prepends the name of a variable that is defined in the addresstomoreinfo.php page that will be identified by $var=$_GET['image_id'];
Other php, html, css elements are involved in the big picture of accomplishing this. A good source for begining information is http://www.w3schools.com/ I also live and die by the php manual linked to above
I use tables and JavaScript to do this.
Data in a SQL database is, by nature, tabular. So I just select the data and create a table. Then, to drill down (when I need do), I provide a JavaScript "more" functionality and use CSS to hide/display the additional data.
You could begin with the PHP manual. It's rather well organised now. But now that my sarcastic bit's out of the way...
One of the best ways to work with your database (at the moment, your choice is MySQL, but this could change) is to abstract your code from direct interaction with it.
A tool such as ADODB is well worth getting to know and makes the task of "obtain a list of all the rows in the database" rather trivial.
The main advantage of this is that it insulates you somewhat from having to rewrite lots of code if you find you need to migrate your application to a server with a different database running on it.
Better still (imho) would be to look at a framework such as Zend's (well, they do MAKE php afterall) with it's DB abstraction called Zend_Db. This might be overkill for you right now as it appears, from looking at your other questions, that you're quite new to PHP/MySQL development.
Also good: Smarty (for abstracting your presentation from your logic)
I tend to use two separate pages. One to list, which links to the one that shows the detailed record. The one that lists passes an ID parameter on the link (ie. show.php?id=145), as for the show.php page will get that parameter from $_GET['id'].
This is the simplest approach to your problem.
If you're not a programmer, but want to use php to show what's inside your mysql tables, perhaps phpMyAdmin is what you're looking for?
If you're building a simple database-driven application, and you're just starting to learn PHP, the approach I'd recommend is to use a framework that generates these for you. Take a look at QCodo (http://www.qcodo.com), and in particular, this tutorial video: http://www.qcodo.com/view.php/demo_1_live
I think you don't really know what you're asking for! :-)
With a suitable framework, database and object abstraction layers, this is trivial (I've done it several times). But they are not trivial to write from scratch and not helpful for learning PHP from the basics. Unless you've done this in other languages.
OTOH, doing it all directly is still a good exercise (as #kevtrout has described), as long as you're willing to re-engineer the code repeatedly (even if you never really do) to develop suitable abstraction. IMO, there is far too much PHP kicking around that has long outgrown such a simple structure.