im looking to create a web app using php, mysql. im planning to write it in classes.
i have created 3 classes: CBaseUser, CWaiter, CBaseAuth
so basically CBaseUser will be a parent class to CWaiter and CBaseAuth contains things like GetPasswdLen(), CreatePasswd(), GetToken().
so right now im heading to do the rest of the program which requre insert,delete,update, login, etc
im a little confuse here because im not sure where should I do my sql query function. should i do it in CWaiter?
could someone enlighten me about OOP in PHP? like the best practice to create a PHP web program.
If you are doing all OO you might want to take a look on php's pear db before going deeper into sql transactions. pear::db makes possible to do database agnostic systems, meaning that you can run it on mysql, postgre, etc without changing a single line of code.
See here for a similar question. You really want to avoid repeating structurally similar queries, but too few programmers know how to do that in a 'greenfields' project.
im a little confuse here because im not sure where should I do my sql query function. should i do it in CWaiter?
You could, but it is generally considered good practice to keep your SQL queries in a separate place (ie separate set of source code files) to your business logic.
"MVC" is a pattern people often talk about which involves separating the code for "Model" (ie anything that needs to know your database structure, eg all your SQL) "View" (anything that draws the UI, which typically means the template engine) and "Controller" (all business logic, drawing it all together).
This would mean that you'd have a different group of classes with names such as CBaseUserDB or CWaiterDB (or whatever) for anything that needs to update/query the database. This is a simplified example just to illustrate my point.
The thinking behind separating this is that SQL, template code, and business logic all intertwined can be messy or hard to follow.
You may also want to look at PDO which is a more modern way to access a database than for example mysql_ and mysqli_. It contains some extra features such as prepared statements, but the main benefit in my opinion is that it means your knowledge will be more future proof and you'll be able to adapt to different database APIs easily. Unlike the previous answer I don't much fancy higher level abstraction like pear::db but that's up to your personal opinion.
Related
I quite often see in PHP, WordPress plugins specifically, that people write SQL directly in their plugins... The way I learnt things, everything should be handled in layers... So that if one day the requirements of a given layer change, I only have to worry about changing the layer that everything interfaces.
Right now I'm writing a layer to interface the database so that, if something ever changes in the way I interact with databases, all I have to do is change one layer, not X number of plugins I've created.
I feel as though this is something that other people may have come across in the past, and that my approach my be inefficient.
I'm writing classes such as
Table
Column
Row
That allow me to create database tables, columns, and rows using given objects with specific methods to handle all their functions:
$column = new \Namespace\Data\Column ( /* name, type, null/non-null, etc... */ );
$myTable = new \Namespace\Data\Table( /* name, column objects, and indexes */ );
\Namespace\TableModel.create($myTable);
My questions are...
Has someone else already written something to provide some separation between different layers?
If not, is my approach going to help at all in the long run or am I wasting my time; should I break down and hard-code the sql like everyone else?
If it is going to help writing this myself, is there any approach I could take to handle it more efficiently?
You seem to be looking for an ORM.
Here is one : http://www.doctrine-project.org/docs/orm/2.0/en/tutorials/getting-started-xml-edition.html
To be honest, I'd just hard-code the SQL, because:
Everyone else does so too. Big parts of WordPress would need to be rewritten, if they would ever wish to change from MySQL to something else. It would just be a waste of time to write your perfect layer for your plugin, if the rest of the whole system still only works with hard-coded SQL.
We don't live in a perfect world. Too much abstraction will - soon or late - end up in performance and other issues, which I don't even think of yet. Keep it simple. Also, using SQL you can benefit from some performance "hacks", which maybe won't work for other systems.
SQL is a widely accepted standard and can already be seen as abstraction layer. for example there's even the possibility to access Facebook's Graph via SQL-like syntax (see FQL). If you want to change to another data-source, you'll probably find some layer wich supports SQL-syntax anyways! In that sense, you could even say SQL already is some kind of abstraction layer.
But: if you decide to use SQL, be sure to use WordPress' $wpdb. Using that, you're on the safe side, as WordPress takes care of connecting to the database, forming the queries, etc. If, one day, WordPress will decide to change from databases to something else, they'll need to create a $wpdb-layer to that new source - for backwards compatibility. Also, many general requests already are in $wpdb as functions (such as $wpdb->insert()), so there's no direct need to hard-code SQL.
If however, you decide to use such an abstraction layer: Wikipedia has more information.
Update: I just found out that the CMS Drupal uses a database abstraction layer - but they still use SQL to form their queries, for all the different databases! I think that shows pretty clearly, how SQL can already be used as an abstraction layer.
I have a class that helps me to handle users.
For example:
$user = new User("login","passw");
$name = $user->getName();
$surname = $user->getSurname();
$table = $user->showStats();
All these methods have SQL queries inside. Some actions require only one sql queries, some - more than one. If database structure changes - it will be difficult to change all queries (class is long). So I thought to keep SQL queries away from this class. But how to do this?
After reading this question I've known about Stored Procedures. Does it mean, that now one action requires only one SQL query (call of Stored Procedure)? But how to organize separation sql from php? Should i keep sql-queries in an array? Or may be it should be an sql-queries class. If yes, how to organise this class (maybe what pattern I should learn)
This is a surprisingly large topic, but I have a few suggestions to help you on your way:
You should to look into object-relational mapping, in which an object automatically generates SQL queries. Have a look at the Object-Relational Mapping and Active Record articles for an overview. This will keep your database code minimal and make it easier if your table structure changes.
But there is no silver bullet here. If your schema changes you will have to change your queries to match. Some people prefer to deal with this by encapsulating their query logic within database views and stored procedures. This is also a good approach if you are consistent, but keep in mind that once you start writing stored procedures, they are going to be tied heavily to the particular database you are using. There is nothing wrong with using them, but they are going to make it much more difficult for you to switch databases down the road - usually not an issue, but an important aspect to keep in mind.
Anyway, whatever method you choose, I recommend that you store your database logic within several "Model" classes. It looks like you are doing something similar to this already. The basic idea is that each model encapsulates logic for a particular area of the database. Traditionally, each model would map to a single table in the DB - this is how the Ruby on Rails active record class works. It is a good strategy as it breaks down your database logic into simple little "chunks". If you keep all of the database query logic within a single file it can quickly grow out of control and become a maintenance nightmare - trust me, I've been there!
To get a better understanding of the "big picture", I recommend you spend some time reading up on web Model-View-Controller (MVC) architecture. You will also want to look at the established PHP MVC frameworks, such as CodeIgniter, Kohaha, CakePHP, etc. Even if you do not use one - although I recommend you do - it would be helpful to see how these frameworks organize your code.
I would say you should look into implementing the "repository" design pattern in your code.
A good answer to how to implement this would be too long for this space, so I'll post a couple of PHP-oriented references:
travis swicegood -- Repository Pattern in PHP
Jon Lebensold -- A Repository Pattern in PHP
You are on the right lines if you use separation of concerns to separate your business logic from your data access logic you will be in a better place.
Judging by your "there are already 2K lines of code" statement, you're either maintaining something, or midway through developing something.
Both Faust and Justin Ethier make good recommendations - "how should I separate my database access from my application code" is one of the oldest, and most-answered, questions in web development.
Personally, I like MVC - it's pretty much the default paradigm for web development, it balances maintainability with productivity, and there are a load of frameworks to support you while you're doing it.
You may, of course, decide that re-writing your app from scratch is too much effort - in which case the repository pattern is a good halfway house.
Either way, you need to read up on refactoring - getting from where you are to where you want to be is going to be tricky. I recommend the book by Fowler, as a starter.
Could you explain more about why your database schema may change? That's usually a sign of trouble ahead.....
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
Other than standard OO concepts, what are some other strategies that allow for producing good, clean PHP code when a framework is not being used?
Remember: MVC, OOP and tiers are design concepts, not language constructs, nor file-structuring.
For me, this means that when not using a framework, and when there's not different teams for programming and designing; there's no value in using another template system on top of PHP (which is a template language). Also, separating code from layout doesn't necessarily mean doing it on different files.
This is how i used to do for one-off, seldom expanded, PHP web apps:
write a 'general utilities' file, there i put some formatting/sanitising functions, as well as a few DB access functions:
getquery(): given a SQL, returns a result object
getrecord(): given a SQL, returns a record object (and closes the query)
getdatum(): given a SQL, returns a single field (and closes the query)
put all configurations (DB access, some URL prefixes, etc) on a 'config.php' file
write a model layer, either one file, or one for each object you store on DB. There, will be all the SQL constants, present a higher-level API, based on your conceptual objects, not on DB records.
that's your 'framework', then you write the 'presentation' layer:
one PHP file for each page, starts with some simple code to fetch the objects needed, followed by HTML with interspeced PHP code, just to 'fill in the holes'. with very few exceptions, the most complex code there should be for loops. I make a rule to use only one-liners, the ?> should be in the same line as the opening <?php
each data-entry form should point to a small PHP without any HTML, that simply get's the POST data, enters into the DB, and forwards to the calling page.
and that's it. If working alone, it has all the separation of intents you need, without drowning in a lot of files for a single user action. Each page as seen by the user is managed by a single PHP file.
It's even easy to maintain, after a few months without looking at the code, since it's easy to test the app, taking note of the filenames in the URL field of the browser. This guides you directly to the relevant code.
(nowadays, of course, i'm using Django for almost everything...)
If you ever find yourself mixing HTML and code, just STOP. You're, well...
You're doing it wrong! http://dennisjudd.com/albums/cute_cats/wrong_mike.jpg
I'd say pretty much the same as for any other language:
Don't optimise prematurely
Keep methods small
Practise DRY
Practise data-driven programming
Use sensible shortcuts (e.g. ternary operator)
Format your code well so that it can be understood by others
Don't use OO blindly
Always check return codes for errors
Enable the highest warning level and ensure your code doesn't produce any warnings
Be very careful when it comes to typing issues (this goes for all weakly-typed languages). The '===' operator is your friend.
Really this question is quite language agnostic, as it applies to most languages where you choose to "roll your own". Two suggestions I would make would be :
Firstly, just because you aren't using a framework doesn't mean you can't adopt the patterns for segregating code. The MVC pattern is the minimum you should consider when arranging you source code - it makes for a much cleaner and easier to maintain collection of source code, even if the application doesn't entirely follow the routing processes associated with frameworks, having code that "does" things separated out from that which "represents" things is very beneficial.
Secondly, just because you've chosen not to use a full framework, doesn't mean you need to reinvent the wheel. Utilise pre-packaged libraries sensibly in order to solve a specific problems. Two good examples would be a logging framework (log4php) and a front-end rendering/templating solution (Smarty).
Stay away from globals as best as possible :-D
If you really do follow OO concepts, like separation of concerns, your code will be pretty good, but here are a few suggestions:
Framework or not, use MVC.
I can't stress enough how important it is to never mix your logic with your HTML. In an HTML file, PHP should be used only as a template language and nothing more.
Use a DBAL.
Separate your design from your content. A common method for doing this is using CSS heavily and having header and footer files containing the bulk of site layout.
Have a single file for option constants, like DB credentials, FTP credentials, etc.
make sure to follow standard practices of separation of concerns. What this means is try not to mix you business and data layer with your UI.
Even If you don't use a framework, use a template engine. By using templates, you'll seperate the logic and presentation of your application. Then design, code and format the logic part like what you would do with any other language. Make the "designers" design the user interface :)
OO is not strictly necessary: it was possible to write good code in PHP < 5 too. Good procedural code, well separated into files and directories by 'logical distance' should also keep you safe. Notice, though, how this starts resembling OO from afar.
Best thing would be to be consistent: I've seen a project where Smarty was used in most pages except one -the most complex, go figure-.
Take advantage of PHP's in-built extensions - MySQLi for example. As these become more object-oriented the requirement for frameworks becomes less.
For example, I could create a useful TwitterApp by using the following extensions and no actual framework besides a core class to tie instances together.
MySQLi for database (PDO if you need DAL)
SimpleXML for RSS/API reading
Smarty for templating
I might need to make a few helper classes for things like Login but my usual pair of classes (DAL and TPL) are made obsolete by two very well worked extensions.
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.