PHP 101: PHP For the Absolute Beginner Novice PHP101 PHP5 Tutorials by Vikram Vaswani | 10 comments | Saturday, July 17, 2004 This area is intended for everyone new to PHP. It opens with a series of informal, entertaining tutorials written by Vikram Vaswani, founder and CEO of Melonfire. These tutorials build on a previously-published 5-part series which has now been updated and extended to embrace PHP 5, making parts of it suitable for those of you who already have worked with PHP 4 in the past. If you came here to learn about elementary PHP 4 or basic PHP 5, this is for you. Enjoy! PHP 101 (part 1): Down the Rabbit Hole [July 17, 2004] An introduction to PHP’s variables and operators. PHP 101 (part 2): Calling All Operators [July 18, 2004] The rest of the PHP operators (there are many), and simple form processing. PHP 101 (PART 3): Looping the Loop [July 19, 2004] Basic control structures explained. PHP 101 (PART 4): The Food Factor [July 20, 2004] Arrays, PHP array functions, and what it all means. PHP 101 (PART 5): Rank and File [July 21, 2004] Everything you’re ever likely to need to know about dealing with external files from a PHP script. PHP 101 (PART 6): Functionally Yours [July 28, 2004] All about functions, arguments, passing by reference, globals and scope. PHP 101 (PART 7): The Bear Necessities [August 07, 2004] A gentle introduction to object oriented programming in PHP 4 and PHP 5. PHP 101 (PART 8): Databases and Other Animals [August 31, 2004] All about connecting to a MySQL database from PHP, using the mysql or mysqli extensions. PHP 101 (PART 9): SQLite My Fire! [September 16, 2004] Introducing another database: SQLite. PHP 101 (part 10): A Session In The Cookie Jar [October 3, 2004] Sessions and cookies – how to keep track of visitors to your site. PHP 101 (part 11): Sinfully Simple [October 3, 2004] An introduction to PHP’s easiest method for dealing with XML. PHP 101 (part 12): Bugging Out [January 30, 2005] Basic error handling. PHP 101 (part 13): The Trashman Cometh [February 27, 2005] A primer in basic security. PHP 101 (part 14): Going to the Polls [March 8, 2005] Putting the pieces together – a first Web application. PHP 101 (part 15): No News is Good News [June 4, 2005] Creating a simple RSS news aggregator. Comments Add Comment Monday, September 11, 2006 PHP USED AS OOPS 11:23PM PDT preeti1910 Very socked to read that Php is used as object oriented programming language. I want to know the difference between PHP3,PHP4 and PHP 5. Thanks Preeti Thursday, September 28, 2006 FANTASTIC TUTORIALS 12:55AM PDT Frode [unregistered] Highly recommended, and even funny to read. The "my standard response" example is genius :) WHERE TO NEXT? 9:02AM PDT Anonymous User [unregistered] Where do i go next? Php.net manual? Saturday, October 7, 2006 GREAT TUTUTORIAL!! 6:10PM PDT Juan [unregistered] Thank you very much for such an interesting PHP Tutorial. 10/10 :) Wednesday, October 11, 2006 PHP 101 FOR BEGINNERS ITS AMAZING 7:29PM PDT sachinanbu
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
PHP 101: PHP For the Absolute BeginnerNovice PHP101 PHP5 Tutorials
by Vikram Vaswani | 10 comments | Saturday, July 17, 2004
This area is intended for everyone new to PHP. It opens with a series of informal, entertaining tutorials written by Vikram Vaswani, founder and CEO of Melonfire. These tutorials build on a previously-published 5-part series which has now been updated and extended to embrace PHP 5, making parts of it suitable for those of you who already have worked with PHP 4 in the past.
If you came here to learn about elementary PHP 4 or basic PHP 5, this is for you. Enjoy!
PHP 101 (part 1): Down the Rabbit Hole [July 17, 2004]An introduction to PHP’s variables and operators.
PHP 101 (part 2): Calling All Operators [July 18, 2004]The rest of the PHP operators (there are many), and simple form processing.
PHP 101 (PART 3): Looping the Loop [July 19, 2004]Basic control structures explained.
PHP 101 (PART 4): The Food Factor [July 20, 2004]Arrays, PHP array functions, and what it all means.
PHP 101 (PART 5): Rank and File [July 21, 2004]Everything you’re ever likely to need to know about dealing with external files from a PHP script.
PHP 101 (PART 6): Functionally Yours [July 28, 2004]All about functions, arguments, passing by reference, globals and scope.
PHP 101 (PART 7): The Bear Necessities [August 07, 2004]A gentle introduction to object oriented programming in PHP 4 and PHP 5.
PHP 101 (PART 8): Databases and Other Animals [August 31, 2004]All about connecting to a MySQL database from PHP, using the mysql or mysqli extensions.
PHP 101 (PART 9): SQLite My Fire! [September 16, 2004]Introducing another database: SQLite.
PHP 101 (part 10): A Session In The Cookie Jar [October 3, 2004]Sessions and cookies – how to keep track of visitors to your site.
PHP 101 (part 11): Sinfully Simple [October 3, 2004]An introduction to PHP’s easiest method for dealing with XML.
PHP 101 (part 12): Bugging Out [January 30, 2005]Basic error handling.
PHP 101 (part 13): The Trashman Cometh [February 27, 2005]A primer in basic security.
PHP 101 (part 14): Going to the Polls [March 8, 2005]Putting the pieces together – a first Web application.
PHP 101 (part 15): No News is Good News [June 4, 2005]Creating a simple RSS news aggregator.
Comments
Add Comment
Monday, September 11, 2006
PHP USED AS OOPS11:23PM PDT � preeti1910
Very socked to read that Php is used as object oriented programming language.I want to know the difference between PHP3,PHP4 and PHP 5.
Highly recommended, and even funny to read. The "my standard response" example is genius :)
WHERE TO NEXT?9:02AM PDT � Anonymous User [unregistered]
Where do i go next? Php.net manual?
Saturday, October 7, 2006
GREAT TUTUTORIAL!!6:10PM PDT � Juan [unregistered]
Thank you very much for such an interesting PHP Tutorial.10/10:)
Wednesday, October 11, 2006
PHP 101 FOR BEGINNERS ITS AMAZING7:29PM PDT � sachinanbu
I Read all the content for the ZEND's PHP Tutorial
Its really amazing and its very esily understandable
i really know lots of things about php
its wonderful
amzing work by ZEND!I really THANK YOU and WISH ZEND TEAM
Monday, October 30, 2006
GREAT WORK ZEND!1:15AM PST � janantha
I took 24 hrs off from my uni work just to learn php and i #wentthrough each of the tutorials. They were absolutely easy to understand and the humour in it really makes a person to readit.I understood the OOP nature of php as ive coded in C++ java before. and php has the easiest syntax. What a languageEasiest scripting language ever thanks to zend. I am now starting to progress into more advanced tutorials. Keep upthe good work
Friday, November 10, 2006
FONT SIZE7:21AM PST � Anonymous User [unregistered]
This tutorial looks excellent, but the font size is way too small. I am very concerned about the trend to smallerand smaller font sizes in ALL web pages, but this particular tutorial could be improved by making the font larger. When printed, it is nearly impossible to read; it's barely readable in a browser (and yes, I am using FireFox's ability to expand fonts, but that doesn't help when printing). Thanks!
Saturday, January 6, 2007
EXCELLENT TUTORIAL8:34AM PST � Anonymous User [unregistered]
This is an excellent tutorial. I already have some programing experience. So the concepts are not new to me,but you help me see and understand the implementations in PHP very well.
Sunday, February 11, 2007
GREAT INSTRUCTIONS12:32PM PST � Karen [unregistered]
ARE YOU AN INSTRUCTOR? YOU SHOULD BE!!! YOUR PHP TUTORIALS HAS BEEN VERY INTERESTING ANDINFORMATIVE. I'M GETTING READY TO DO MY FIRST CODE
Sunday, June 24, 2007
HEADY AND JUSTIFIED PRAISE8:53AM PDT � DobbyCodes
I was referred to your tutorials by a programming professional. I consider that to be very high praise, indeed.
Having nothing more in the way of coding experience than an online course I took in HTML 4.0, I am in desperate need of finding gainful employment.
I was not thrilled with the prospect of returning to the workforce as a secretary, but my programmer friend informed me that your site would be a wonderful place to begin learning PHP. And he was RIGHT!
The sense of humor evidenced in the lessons makes the learning lighthearted and fun. I'm very excited topursue this course of study and become truly proficient in it.
Many thanks for all the work that was put into this series. It really shows and I am extremely grateful you'vemade it available.
PHP 101 (part 1): Down the Rabbit HoleNews Novice PHP101 PHP4 PHP5 Tutorials
by Vikram Vaswani | 28 comments | Saturday, July 17, 2004
The Only Acronym You'll Ever NeedThe Right EnvironmentStart Me UpA Case of IdentityAn Equal MusicNot My TypeMarket ValueStringing Things Along
The Only Acronym You'll Ever Need
If you're new to Web development, you could be forgiven for thinking that it consists of no more than a mass ofacronyms, each one more indecipherable than the last. ASP, CGI, SOAP, XML, HTTP - the list seemsnever-ending, and the sheer volume of information on each of these can discourage the most avid programmer.But before you put on your running shoes and flee, there's a little secret you should know. To put together acutting-edge Web site, chock full of all the latest bells and whistles, there's only one acronym you really need toknow:
PHP
Now, while you have almost certainly heard of PHP, you may not be aware of just how powerful the language is,and how much it can do for you. Today, PHP has the enviable position of being the only open-source server-sidescripting language that's both fun and easy to learn. This is not just advertising: recent surveys show that morethan 16,000,000 Web sites use PHP as a server side scripting language, and the language also tops the list ofmost popular Apache modules.
Why, you ask? The short answer: it's powerful, it's easy to use, and it's free. Extremely robust and scalable, PHPcan be used for the most demanding of applications, and delivers excellent performance even at high loads.Built-in database support means that you can begin creating data-driven applications immediately, XML supportmakes it suitable for the new generation of XML-enabled applications, and the extensible architecture makes iteasy for developers to use it as a framework to build their own custom modules. Toss in a great manual, aknowledgeable developer community and a really low price (can you spell f-r-e-e?) and you've got the makingsof a winner!
My goal in this series of tutorials is very simple: I'll be teaching you the basics of using PHP, and showing youwhy I think it's the best possible tool for Web application development today. I'll be making no assumptions about your level of knowledge, other than that you can understand basic HTML and have a sense of humor. Andbefore you ask... Yes, this series covers both PHP 4 and PHP 5, with new PHP 5 features flagged for easyreference.
Let's get going!
The Right Environment
PHP is typically used in combination with a Web server like Apache. Requests for PHP scripts are received by theWeb server, and are handled by the PHP interpreter. The results obtained after execution are returned to theWeb server, which takes care of transmitting them to the client browser. Within the PHP script itself, the sky'sthe limit - your script can perform calculations, process user input, interact with a database, read and writefiles... Basically, anything you can do with a regular programming language, you can do inside your PHP scripts.
From the above, it is clear that in order to begin using PHP, you need to have a proper developmentenvironment set up.
This series will focus on using PHP with the Apache Web server on Linux, but you can just as easily use PHP withApache on Windows, UNIX and Mac OS. Detailed instructions on how to set up this development environment oneach platform are available in the online manual, at http://www.php.net/manual/en/installation.php - or you can just download a copy of PHP 5 from http://www.php.net and read the installation instructions.
Go do that now, and come back when you've successfully installed and tested PHP.
Start Me Up
There's one essential concept that you need to get your mind around before we proceed further. Unlike CGIscripts, which require you to write code to output HTML, PHP lets you embed PHP code in regular HTML pages,and execute the embedded PHP code when the page is requested.
These embedded PHP commands are enclosed within special start and end tags, like this:
<?php
... PHP code ...
?>
Here's a simple example that demonstrates how PHP and HTML can be combined:
<html>
<head></head>
<body>
Agent: So who do you think you are, anyhow?
<br />
<?php
// print output
echo 'Neo: I am Neo, but my people call me The One.';
?>
</body>
</html>
Not quite your traditional "Hello, World" program... but then again, I always thought tradition was over-rated.
Save the above script to a location under your Web server document root, with a .php extension, and browse toit. You'll see something like this:
Look at the HTML source:
<html>
<head></head>
<body>
Agent: So who do you think you are, anyhow?
<br />
Neo: I am Neo, but my people call me The One.
</body>
</html>
What just happened? When you requested the script above, Apache intercepted your request and handed it offto PHP. PHP then parsed the script, executing the code between the <?php...?> marks and replacing it with the
output of the code run. The result was then handed back to the server and transmitted to the client. Since theoutput contained valid HTML, the browser was able to render it for display to the user.
A close look at the script will reveal the basic syntactical rules of PHP. Every PHP statement ends in asemi-colon. This convention is identical to that used in Perl, and omitting the semi-colon is one of the mostcommon mistakes newbies make. That said, it is interesting to note that a semi-colon is not needed to terminatethe last line of a PHP block. The PHP closing tag includes a semi-colon, therefore the following is perfectly validPHP code:
<?php
// print output
echo 'Neo: I am Neo, but my people call me The One.'
?>
It's also possible to add comments to your PHP code, as I've done in the example above. PHP supports bothsingle-line and multi-line comment blocks:
<?php
// this is a single-line comment
/* and this is a
multi-line
comment */
?>
Blank lines within the PHP tags are ignored by the parser. Everything outside the tags is also ignored by theparser, and returned as-is. Only the code between the tags is read and executed.
A Case of Identity
Variables are the bread and butter of every programming language... and PHP has them too. A variable can bethought of as a programming construct used to store both numeric and non-numeric data; the contents of avariable can be altered during program execution. Finally, variables can be compared with each other, and you -the programmer - can write code that performs specific actions on the basis of this comparison.
PHP supports a number of different variable types: integers, floating point numbers, strings and arrays. In manylanguages, it's essential to specify the variable type before using it: for example, a variable may need to bespecified as type integer or type array. Give PHP credit for a little intelligence, though: it automagically
determines variable type by the context in which it is being used!
Every variable has a name. In PHP, a variable name is preceded by a dollar ($) symbol and must begin with aletter or underscore, optionally followed by more letters, numbers and/or underscores. For example, $popeye,
$one and $INCOME are all valid PHP variable names, while $123 and $48hrs are invalid.
Note that variable names in PHP are case sensitive, so $me is different from $Me or $ME.
Here's a simple example that demonstrates PHP's variables:
<html>
<head></head>
<body>
Agent: So who do you think you are, anyhow?
<br />
<?php
// define variables
$name = 'Neo';
$rank = 'Anomaly';
$serialNumber = 1;
// print output
echo "Neo: I am <b>$name</b>, the <b>$rank</b>. You can call me by my serial number,
<b>$serialNumber</b>.";
?>
</body>
</html>
Here, the variables $name, $rank and $serialNumber are first defined with string and numeric values, and then
substituted in the echo() function call. The echo() function, along with the print() function, is commonly used
to print data to the standard output device (here, the browser). Notice that I've included HTML tags within thecall to echo(), and those have been rendered by the browser in its output. You can do this too. Really.
An Equal Music
To assign a value to a variable, you use the assignment operator: the = symbol. This is used to assign a value(the right side of the equation) to a variable (the left side). The value being assigned need not always be fixed;it could also be another variable, an expression, or even an expression involving other variables, as below:
<?php
$age = $dob + 15;
?>
Interestingly, you can also perform more than one assignment at a time. Consider the following example, whichassigns three variables the same value simultaneously:
<?php
$angle1 = $angle2 = $angle3 = 60;
?>
Not My Type
Every language has different types of variable - and PHP is no exception. The language supports a wide varietyof data types, including simple numeric, character, string and Boolean types, and more complex arrays andobjects. Here's a quick list of the basic ones, with examples:
Boolean: The simplest variable type in PHP, a Boolean variable, simply specifies a true or false value.<?php
$auth = true;
?>
Integer: An integer is a plain-vanilla whole number like 75, -95, 2000 or 1.<?php
$age = 99;
?>
Floating-point: A floating-point number is typically a fractional number such as 12.5 or 3.141592653589.Floating point numbers may be specified using either decimal or scientific notation.<?php
$temperature = 56.89;
?>
String: A string is a sequence of characters, like "hello" or "abracadabra". String values may be enclosed ineither double quotes ("") or single quotes(''). (Quotation marks within the string itself can be "escaped" with abackslash (\) character.) String values enclosed in double quotes are automatically parsed for special charactersand variable names; if these are found, they are replaced with the appropriate value. Here's an example:<?php
$identity = 'James Bond';
$car = 'BMW';
// this would contain the string "James Bond drives a BMW"
$sentence = "$identity drives a $car";
echo $sentence;
?>
To learn more about PHP's data types, visit http://www.php.net/manual/en/language.types.php.
Market Value
If variables are the building blocks of a programming language, operators are the glue that let you buildsomething useful with them. You've already seen one example of an operator - the assignment operator -, whichlets you assign a value to a variable. Since PHP believes in spoiling you, it also comes with operators forarithmetic, string, comparison and logical operations.
A good way to get familiar with operators is to use them to perform arithmetic operations on variables, as in thefollowing example:
Looks complex? Don't be afraid - it's actually pretty simple. The meat of the script is at the top, where I've setup variables for the unit cost and the quantity. Next, I've performed a bunch of calculations using PHP's variousmathematical operators, and stored the results of those calculations in different variables. The rest of the scriptis related to the display of the resulting calculations in a neat table.
If you'd like, you can even perform an arithmetic operation simultaneously with an assignment, by using the twooperators together. The two code snippets below are equivalent:
<?php
// this...
$a = 5;
$a = $a + 10;
// ... is the same as this
$a = 5;
$a += 10;
?>
If you don't believe me, try echoing them both.
Stringing Things Along
Why stop with numbers? PHP also allows you to add strings with the string concatenation operator, representedby a period (.). Take a look:
<?php
// set up some string variables
$a = 'the';
$b = 'games';
$c = 'begin';
$d = 'now';
// combine them using the concatenation operator
// this returns 'the games begin now<br />'
$statement = $a.' '.$b.' '.$c.' '.$d.'<br />';
print $statement;
// and this returns 'begin the games now!'
$command = $c.' '.$a.' '.$b.' '.$d.'!';
print $command;
?>
As before, you can concatenate and assign simultaneously, as below:
<?php
// define string
$str = 'the';
// add and assign
$str .= 'n';
// str now contains "then"
echo $str;
?>
To learn more about PHP's arithmetic and string operators, visithttp://www.php.net/manual/en/language.operators.arithmetic.php andhttp://www.php.net/manual/en/language.operators.string.php.
That's about it for this tutorial. You now know all about the basic building blocks and glue of PHP - its variablesand operators. In Part Two of this series, I'll be using these fundamental concepts to demonstrate PHP'spowerful form processing capabilities.
Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Friday, August 4, 2006
Q1:09AM PDT � zarezadeh
Is there any data structure like C++ data structures or other programming languages?( I means a thing like linkedlisr, tree, ...)
Wednesday, August 16, 2006
THANK YOU!7:20AM PDT � p1agu3 [unregistered]
I really appreciate the work you've done on these tutorials. It should be very helpful. =)
Monday, August 28, 2006
I APPRCIATE WHAT YOU GIVE US10:11PM PDT � asanga-bandara
This is the first time I use the php. I afriad to that before used this. Now I settle to learn php.
Sunday, September 10, 2006
YOUR PHP TUT/ XAMPP7:29AM PDT � Beata12
Hello,
I am happy that found your tutorials to learn phpMaybe I will learn something because I always wanted. Today I have read your first lesson, it would be good to have here some practical exercises.....
You wrote about php installationI have installed XAMPPWhat you think about it?
Beata
Monday, September 11, 2006
GOOD TUTORIAL11:59AM PDT � Roger [unregistered]
Very good tutorial. I just don't understand where to put the periods for the string concatenation operator. Imean, what are the rules for when and when not to use them? Is there a FAQ somewhere that would answer this question?
Tuesday, September 19, 2006
THANKS!1:50AM PDT � Martin [unregistered]
Well thought out, interesting & very very useful. THANK YOU!
Hi I am new to PHP coding. As a beginner i feel u have done a nice piece of work.Keep it up!
Friday, October 6, 2006
NICE ONE THERE12:12AM PDT � getchybobby
Hello,i'm a begginner,the tutorial is quite helpful and interesting.Thanks
Sunday, October 15, 2006
UH... HUH.9:54PM PDT � Anonymous User [unregistered]
I am new to computer, I read this tutorial. Theres enough funny and entertaining to sustain my attention, but Idon't understand it. Why are we doing this. What does this do. What the hell is a server.
I say this guide need more 'explanation'.
Monday, October 16, 2006
EXCELLENT2:51AM PDT � p1p3m4n [unregistered]
Thanks, an excellent tut, much appreciated.
Wednesday, October 25, 2006
THANK YOU4:52PM PDT � Kat [unregistered]
Freakin amazing...wish my uni lecturers were as entertaining as you!
Friday, November 3, 2006
SEARCH OPTIMIZATION AND SAVE AS2:42AM PST � Sotabound [unregistered]
Hi,I love your tutorials on PHP, very good, especially the one on the Apache install. I have gone down the rabbit hole a little farther than on these first pages, but I do have a couple of very simple questions. When considering search engine optimization, I use my navigation to increase my "organic" SEO. If I have my navigation set up as an include on each page, even the index, will I still get the same optimization? Also, is it good practice to make all of your pages have the PHP extension, even if they mostly consist of HTML? How about the index page, should that be HTML or can it also be PHP.
Thanks again!Sotabound, Burnsville, MN
Thursday, November 23, 2006
FUN TASTIC!!3:33PM PST � Megat2u
Thank a lot!
It's very usefull to me as i am new in PHP & MySQL
Thursday, November 30, 2006
THANKS12:14AM PST � Anonymous User [unregistered]
This is a nice tutorial, and it helped me out. I was trying to make a calculator and I could get the echo stringcorrect but this helped me. It turns out, it was a lot less complex than what I had anticipated.
Monday, December 11, 2006
REGARDUNG THE TUTORIAL11:03PM PST � Jagadish c [unregistered]
first let me congratulate for the greate efford u took to present such an excellent tutorial on php.Its very easyto digest even as a beginner.
Tuesday, December 12, 2006
REGARDUNG THE TUTORIAL2:18AM PST � Jagadish c [unregistered]
first let me congratulate for the greate efford u took to present such an excellent tutorial on php.Its very easyto digest even as a beginner.
PHP 101 4:27AM PST � Anonymous User [unregistered]
Well written and easy to digest. Great job.
SUPER COOL6:08AM PST � alio.ro [unregistered]
I'm a newbee in php and this tutorial is grate.
10x
alio.ro
Tuesday, February 27, 2007
ROCKS11:33AM PST � Mona [unregistered]
Vikram, not only do you have the same name than my favourite author Vikram Seth, but also is this the firstTutorial I don't feel intimidated by. Thanks for boosting my motivation to learn PHP....
Monday, April 2, 2007
MY FIRST CLASS6:59AM PDT � Mwiti Kaimba [unregistered]
My first class was great. I was initially afraid of PHP but you in your wisdom the solution to my fears looks likeits only a few other lessons ahead.
I tried to register in vain. Where do I enter this Zip code, i hail from Nairobi City, Kenya - East Africa
Friday, April 27, 2007
NICE TUTORIALS2:00PM PDT � Al Yaman [unregistered]
When I first looked at a PHP script, I was like, no way thats too complicated. You make PHP sooooo simple.Thanks a lot for these tutorials.
Thursday, May 17, 2007
IMPRESSED6:21AM PDT � russ [unregistered]
Am new to the php scene, have read many articles and tutorials, thou i come back to this site every time,thanks for all the informative and intriging ways of understanding php. it makes understanding this language easier.
IMPRESSED6:23AM PDT � russ [unregistered]
Am new to the php scene, have read many articles and tutorials, thou i come back to this site every time,thanks for all the informative and intriging ways of understanding php. it makes understanding this language easier.
Thursday, June 28, 2007
PHP TUTORIALS...2:23AM PDT � Anonymous User [unregistered]
As a complete novice trudging thru the mine fields of languages to use for developers, I have found php wasthe one to actually, FINALLY, be able to teach me how programming works!! I had read about C, C++, java, Javascript, ASP and ASP.NET, VB,... and more, but never really understood the full meanings of things. Now, after learning a little about php, I can look at almost ANY language, and pretty much understand what's going on! Thanx Guys, and especially the writers of the tutorials. Nd believe it or not, it actually gets easier!!Joosey.
Sunday, July 1, 2007
THANKS A LOT4:15PM PDT � restore_guru
Very useful tutorials, thanks a lot. Hope some day , you could write one specifically for the object orientedcapabilities of PHP.
Sunday, July 8, 2007
GREAT TUTORIAL4:11PM PDT � Anonymous User [unregistered]
I always wanted to learn PHP, but been afraid, that it is too complicated.I do know little bit about programming, such as Visual Basic.After this tutorial I feel much comfortable to learn PHP, since its not very different from other programing languages.Thank you for the tutorial
PHP 101 (part 2): Calling All OperatorsNovice PHP101 PHP5 Tutorials
by Vikram Vaswani | 17 comments | Saturday, July 17, 2004
Not What You ExpectedForm......And FunctionOperating With Extreme CautionA Question of LogicOlder But Not WiserIf Not This, Then What?Spreading ConfusionThe Daily Special
Not What You Expected
In Part One of this series, I gave you a brief introduction to PHP, and how it fits into your Web applicationdevelopment environment. I also taught you the basics of PHP variables, and showed you how to add, multiplyand concatenate them together.
Now that you know the basics, it's time to focus in on one of PHP's nicer features - its ability to automaticallyreceive user input from a Web form and convert it into PHP variables. If you're used to writing Perl code toretrieve form values in your CGI scripts, PHP's simpler approach is going to make you weep with joy. So get thathandkerchief out, and scroll on down.
Form...
Forms have always been one of quickest and easiest ways to add interactivity to your Web site. A form allows you to ask customers if they like your products, casual visitors for comments on your site, and pretty girls for their phone numbers. And PHP can simplify the task of processing the data generated from a Web-based form substantially, as this first example demonstrates. This example contains two scripts, one containing an HTMLform (named form.htm) and the other containing the form processing logic (message.php). Here's form.htm:
<html>
<head></head>
<body>
<form action="message.php" method="post">
Enter your message: <input type="text" name="msg" size="30">
<input type="submit" value="Send">
</form>
</body>
</html>
The critical line in this page is the <form> tag
<form action="message.php" method="post">
...
</form>
As you probably already know, the "action" attribute of the <form> tag specifies the name of the server-side script (message.php in this case) that will process the information entered into the form. The "method" attributespecifies how the information will be passed.
...And Function
Now for the other half of the puzzle: the message.php script. This script reads the data submitted by the userand "does something with it". Here is message.php:
<html>
<head></head>
<body>
<?php
// retrieve form data
$input = $_POST['msg'];
// use it
echo "You said: <i>$input</i>";
?>
</body>
</html>
When you enter some data into form.htm (let's say "Boo"), and submit it, the form processor message.php will read it and display it to you ("You said: Boo"). Thus, whenever a form is submitted to a PHP script, allvariable-value pairs within that form automatically become available for use within the script, through a specialPHP container variable: $_POST. You can then access the value of the form variable by using its "name" insidethe $_POST container, as I did in the script above.
Obviously, PHP also supports the GET method of form submission. All you need to do is change the "method"attribute to "get", and retrieve values from $_GET instead of $_POST. The $_GET and $_POST variables areactually a special type of PHP animal called an array, which I'll be teaching you about shortly. Don't worry toomuch about it at the moment, just make sure you're comfortable with retrieving simple values from a form withPHP, and then scroll on down to learn about some more operators that are useful in this context.
Operating With Extreme Caution
Thus far, the scripts we've discussed have been pretty dumb. All they've done is add numbers and strings, andread back to you the data you typed in yourself - not exactly overwhelming. In order to add some intelligence toyour scripts, you need to know how to construct what geeks call a "conditional statement" - a statement whichlets your script perform one of a series of possible actions based on the result of a comparison test. And sincethe basis of a conditional statement is comparison, you first need to know how to compare two variables and
determine whether they're identical or different.
You've already seen some of PHP's arithmetic and string operators. However, the language also comes withoperators designed specifically to compare two values: the so-called "comparison operators". Here's an examplethat demonstrates them in action:
<?php
/* define some variables */
$mean = 9;
$median = 10;
$mode = 9;
// less-than operator
// returns true if left side is less than right
// returns true here
$result = ($mean < $median);
print "result is $result<br />";
// greater-than operator
// returns true if left side is greater than right
// returns false here
$result = ($mean > $median);
print "result is $result<br />";
// less-than-or-equal-to operator
// returns true if left side is less than or equal to right
// returns false here
$result = ($median <= $mode);
print "result is $result<br />";
// greater-than-or-equal-to operator
// returns true if left side is greater than or equal to right
// returns true here
$result = ($median >= $mode);
print "result is $result<br />";
// equality operator
// returns true if left side is equal to right
// returns true here
$result = ($mean == $mode);
print "result is $result<br />";
// not-equal-to operator
// returns true if left side is not equal to right
// returns false here
$result = ($mean != $mode);
print "result is $result<br />";
// inequality operator
// returns true if left side is not equal to right
// returns false here
$result = ($mean <> $mode);
print "result is $result";
?>
The result of a comparison test is always Boolean: either true (1) or false (0 - which doesn't print anything).This makes comparison operators an indispensable part of your toolkit, as you can use them in combination witha conditional statement to send a script down any of its multiple action paths.
PHP 4.0 also introduced a new comparison operator, which allows you to test both for equality and type: the=== operator. The following example demonstrates it:
<?php
/* define two variables */
$str = '10';
$int = 10;
/* returns true, since both variables contain the same value */
$result = ($str == $int);
print "result is $result<br />";
/* returns false, since the variables are not of the same type even though they have the same
value */
$result = ($str === $int);
print "result is $result<br />";
/* returns true, since the variables are the same type and value */
$anotherInt = 10;
$result = ($anotherInt === $int);
print "result is $result";
?>
Read more about PHP's comparison operators athttp://www.php.net/manual/en/language.operators.comparison.php.
A Question of Logic
In addition to the comparison operators I used so liberally above, PHP also provides four logical operators, whichare designed to group conditional expressions together. These four operators - logical AND, logical OR, logical XORand logical NOT - are illustrated in the following example:
<?php
/* define some variables */
$auth = 1;
$status = 1;
$role = 4;
/* logical AND returns true if all conditions are true */
// returns true
$result = (($auth == 1) && ($status != 0));
print "result is $result<br />";
/* logical OR returns true if any condition is true */
// returns true
$result = (($status == 1) || ($role <= 2));
print "result is $result<br />";
/* logical NOT returns true if the condition is false and vice-versa */
// returns false
$result = !($status == 1);
print "result is $result<br />";
/* logical XOR returns true if either of two conditions are true, or returns false if both
conditions are true */
// returns false
$result = (($status == 1) xor ($auth == 1));
print "result is $result<br />";
?>
Logical operators play an important role in building conditional statements, as they can be used to link togetherrelated conditions simply and elegantly. View more examples of how they can be used athttp://www.php.net/manual/en/language.operators.logical.php.
Older But Not Wiser
Now that you've learnt all about comparison and logical operators, I can teach you about conditional statements.As noted earlier, a conditional statement allows you to test whether a specific condition is true or false, andperform different actions on the basis of the result. In PHP, the simplest form of conditional statement is theif() statement, which looks something like this:
if (condition) {
do this!
}
The argument to if()is a conditional expression, which evaluates to either true or false. If the statementevaluates to true, all PHP code within the curly braces is executed; if it does not, the code within the curlybraces is skipped and the lines following the if() construct are executed.
Let me show you how the if() statement works by combining it with a form. In this example, the user is askedto enter his or her age.
<html>
<head></head>
<body>
<form action="ageist.php" method="post">
Enter your age: <input name="age" size="2">
</form>
</body>
</html>
Depending on whether the entered age is above or below 21, a different message is displayed by theageist.php script:
<html>
<head></head>
<body>
<?php
// retrieve form data
$age = $_POST['age'];
// check entered value and branch
if ($age >= 21) {
echo 'Come on in, we have alcohol and music awaiting you!';
}
if ($age < 21) {
echo "You're too young for this club, come back when you're a little older";
}
?>
</body> </html>
If Not This, Then What?
In addition to the if() statement, PHP also offers the if-else construct, used to define a block of code thatgets executed when the conditional expression in the if() statement evaluates as false.
The if-else construct looks like this:
if (condition) {
do this!
}
else {
do this!
}
This construct can be used to great effect in the last example: we can combine the two separateif()statements into a single if-else statement.
<html>
<head></head>
<body>
<?php
// retrieve form data
$age = $_POST['age'];
// check entered value and branch
if ($age >= 21) {
echo 'Come on in, we have alcohol and music awaiting you!';
}
else {
echo "You're too young for this club, come back when you're a little older";
}
?>
</body>
</html>
Spreading Confusion
If the thought of confusing people who read your code makes you feel warm and tingly, you're going to love theternary operator, represented by a question mark (?). This operator, which lets you make your conditionalstatements almost unintelligible, provides shortcut syntax for creating a single-statement if-else block. So, while you could do this:
<?php
if ($numTries > 10) {
$msg = 'Blocking your account...';
}
else {
$msg = 'Welcome!';
}
?>
You could also do this, which is equivalent (and a lot more fun):
PHP also lets you "nest" conditional statements inside each other. For example, this is perfectly valid PHP code:
<?php
if ($day == 'Thursday') {
if ($time == '0800') {
if ($country == 'UK') {
$meal = 'bacon and eggs';
}
}
}
?>
Another, more elegant way to write the above is with a series of logical operators:
<?php
if ($day == 'Thursday' && $time == '0800' && $country == 'UK') { $meal = 'bacon and eggs'; }
?>
The Daily Special
PHP also provides you with a way of handling multiple possibilities: the if-elseif-else construct. A typical if-elseif-else statement block would look like this:
if (first condition is true) {
do this!
}
elseif (second condition is true) {
do this!
}
elseif (third condition is true) {
do this!
}
... and so on ...
else {
do this!
}
And here's an example that demonstrates how to use it:
<html>
<head></head>
<body>
<h2>Today's Special</h2>
<p>
<form method="get" action="cooking.php">
<select name="day">
<option value="1">Monday/Wednesday
<option value="2">Tuesday/Thursday
<option value="3">Friday/Sunday
<option value="4">Saturday
</select>
<input type="submit" value="Send">
</form>
</body>
</html>
As you can see, this is simply a form which allows you to pick a day of the week. The real work is done by thePHP script cooking.php:
<html>
<head></head>
<body>
<?php
// get form selection
$day = $_GET['day'];
// check value and select appropriate item
if ($day == 1) {
$special = 'Chicken in oyster sauce';
}
elseif ($day == 2) {
$special = 'French onion soup';
}
elseif ($day == 3) {
$special = 'Pork chops with mashed potatoes and green salad';
}
else {
$special = 'Fish and chips';
}
?>
<h2>Today's special is:</h2>
<?php echo $special; ?>
</body>
</html>
In this case, I've used the if-elseif-else control structure to assign a different menu special to eachcombination of days. Note that as soon as one of the if() branches within the block is found to be true, PHP willexecute the corresponding code, skip the remaining if() statements in the block, and jump immediately to thelines following the entire if-elseif-else block.
And that's it for now. To view more examples of conditional statements in action, visithttp://www.php.net/manual/en/language.control-structures.php. In Part Three, I'll be bringing you more controlstructures, more operators and more strange and wacky scripts - so make sure you don't miss it!
Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Monday, September 4, 2006
YOUR WEBSITE IS GREAT!7:07PM PDT � somewoman
This is the first time i have been inspired to leave a comment on a tutorial website.I happened upon your website today and have yet to explore the whole site,however, what little i did explore was extremely informative.
I have been searching none stop for the last month for lessons and tutorials for php...thousands of sites, millions of flashing ads and what little morsels of lessons I did find,were usually confusing or vague...none of it was sinking in.
I swear, i was about to give up and move on to something else.THANK YOU SOOOOOO MUCH!I know my appreciation can't pay the bills but i just had to leave a message for you.
I truly lucked out today....i found a great website with tons of well written lessons displayed without the annoying and distracting ads. PHP is finally sinking in, thanks to your website.
WOW! thank you again!
sincerely,afsaneh
Tuesday, October 10, 2006
WONDERFUL1:20AM PDT � cattaneo1
Clear, simple, rigorous !Great.
EXCELLENT3:00PM PDT � hubrik
Clear and really helpful. Thanks!
Monday, October 16, 2006
QUALITY3:15AM PDT � p1p3m4n [unregistered]
Yehp, this really is first class teaching... Thanks once again.
Wednesday, October 18, 2006
PHP TUTORIAL1:36AM PDT � Madhav [unregistered]
I have been trying to get hold of a decent tutorial. I find that Vivek's set of tutorials is the best anywhere onthe web. Excellent job.
ABOVE1:37AM PDT � Madhav [unregistered]
Ooops! Sorry. I meant to say Vikram's tutorial!
Monday, October 23, 2006
PHP101, PT.28:43AM PDT � radford0222
When I copy, paste & run the code from pgs 2 &3, I get the folloowing error mssg.Notice: PHPDocument3 line 18 - Undefined index: msgpertinent code snippet follows:
<html> <head></head><body> <form action="message.php" method="post"> Enter your message: <input type="text" name="msg" size="30"> <input type="submit" value="Send">
// use it echo "You said: <i>$input</i>"; ?> </body> </html>
//Debug output is "blankmessage.php"
I know it's something that I am not doing (or doing wrong). BUT is sure is frustrating.
Wednesday, November 8, 2006
GOOD TUTORIAL11:59AM PST � peerdeman
like the way you explain things.I can't get to part three though.
Friday, November 10, 2006
RESPONSE TO RADFORD02224:00AM PST � dmerrill
Hi radford0222, I'm a newbie too but decided to see if I could figure out your problem, so here is what I found:
//your code:
<?php // retrieve form data
// next line is line 18$input = $_POST['msg'];
// use it echo "You said: <i>$input</i>"; ?> </body> </html>
Look at your echo statement, it is not concatenated properly and should read:
echo "You said: "."<i>$input</i>";/*the whole statement can't be enclosed in "" but needs to be broken up into twoseparate statements divided by the period. It then works just fine. Hope that helps! */
RESPONSE TO PEERDEMAN4:16AM PST � dmerrill
Go back to the home page of the tutorial and link to part three from there, I couldn't get to it from here either.
http://devzone.zend.com/node/view/id/627
Monday, December 4, 2006
SIMPLY SUPERB3:14PM PST � SAGAR [unregistered]
i'm an intern in my universityI tried to learrn PHP with the help of many tutorials on the net.but this tutorials for the begginers is really a boon.very clear and very approachive for a begginer
Saturday, December 23, 2006
RE: ABOVE ERROR11:33AM PST � Code_Guru
radford0222,
It's been a while since you posted, but I thought I'd post some suggestions in case anyone else encounters the same problem. I believe the error is because you have all the code you posted in a single file. This actuallyneeds to be split into two files as described in part 2 of this tutorial:
<html> <head></head><body> <form action="message.php" method="post"> Enter your message: <input type="text" name="msg" size="30"> <input type="submit" value="Send">
</form> </body> </html>
This above part should be saved to a file named "form.html"
<html> <head></head><body>
<?php // retrieve form data
// next line is line 18$input = $_POST['msg'];
// use it echo "You said: <i>$input</i>"; ?>
</body> </html>
And this part should be saved in a file named "message.php". To use this PHP program, you should open"forms.html" in your webbrowser, enter text into the text box, and click Send. You should NOT open"message.php" directly or you will get the error message that radford describes above.
Friday, March 16, 2007
THANKS A LOT :WAVE:4:50AM PDT � Ella :) [unregistered]
Hey,I just wanted to say thanks a lot, this tut is really great, your style in explaining is very easy to follow and remember and your examples are very instructive and you're funny :) That was about all I wanted to say, onceagain thanks Ella :)
Thursday, April 12, 2007
PHP MADE EASY12:25AM PDT � Kaimba Mwiti [unregistered]
This is great. Even for programmers with good coding experience in other languages will find the tutorialsexciting. I encourage you to keep it up. For PHP developers, the sky is not the limit, PHP is!
Hello..This is a very well organized and interesting set of php tutorials.. I will say one amongst the best out there..Good job man!
Yours,Wakish(http://wakish.info/)
NICE TUTORIAL4:35AM PDT � Wakish [unregistered]
Hello..This is a very well organized and interesting set of php tutorials.. I will say one amongst the best out there..Good job man!
Yours,Wakish(http://wakish.info/)
PHP 101 (part 3): Looping The LoopNovice PHP101 PHP5 Tutorials
by Vikram Vaswani | 5 comments | Monday, July 19, 2004
Going DeeperSwitching Things AroundCreative ConditionalsOne by OneBeing SquareLoop First, Ask Questions LaterDoing it by NumbersTurning the Tables
Going Deeper
If you've been paying attention, you remember that in Part Two I gave you a quick crash course in PHP's basiccontrol structures and operators. I also showed you how PHP can be used to process the data entered into aWeb form. In this tutorial, I'm going to delve deeper into PHP's operators and control structures, showing youtwo new operators, an alternative to the if-else() family of conditional statements, and some of PHP's more
interesting loops. So keep reading... this is just about to get interesting!
Switching Things Around
An alternative to the if-else() family of control structures is PHP's switch-case() statement, which does
almost the same thing. It looks like this:
switch (decision-variable) {
case first condition is true:
do this!
case second condition is true:
do this!
... and so on...
}
Depending on the value of the decision variable, the appropriate case() block is executed. A default block can
also be created, to handle all those occasions when the value of the decision variable does not match any of thelisted case() conditions.
I'll make this a little clearer by re-writing one of my earlier examples in terms of the switch() statement:
<html>
<head></head>
<body>
<?php
// get form selection
$day = $_GET['day'];
// check value and select appropriate item
switch ($day) {
case 1:
$special = 'Chicken in oyster sauce';
break;
case 2:
$special = 'French onion soup';
break;
case 3:
$special = 'Pork chops with mashed potatoes and green salad';
break;
default:
$special = 'Fish and chips';
break;
}
?>
<h2>Today's special is:</h2>
<?php echo $special ?>
</body>
</html>
There are a couple of important keywords here:
The break keyword is used to break out of the switch() statement block and move immediately to the lines
following it.The default keyword is used to execute a default set of statements when the variable passed to switch() does
not satisfy any of the conditions listed within the block.A common newbie mistake here is to forget the break at the end of every case() block. Remember that if you
forget to break out of a case() block, PHP will continue executing the code in all the subsequent case() blocks
it encounters.
For more on the switch() statement, see http://www.php.net/manual/en/control-structures.switch.php.
Creative Conditionals
Normally, when creating and processing forms in PHP, you would place the HTML form in one file, and handleform processing through a separate PHP script. However, with the power of conditional statements at yourdisposal, you can combine both pages into one.
How do you do this? Simple. All you need to do is assign a name to the form submit control, and then check
whether the special $_POST container variable contains that name when the script first loads up. If it does, the
form has already been submitted, and you can process the data; if it does not, that the user has not submittedthe form and you therefore need to generate the initial, unfilled form. Thus, by testing for the presence orabsence of this submit variable, a clever PHP programmer can use a single PHP script to generate both the initial
form, and the output after it has been submitted, as appropriate.
Here's a simple example:
<html>
<head></head>
<body>
<?php
/* if the "submit" variable does not exist, the form has not been submitted - display initial
/* if the "submit" variable exists, the form has been submitted - look for and process form
data */
// display result
$age = $_POST['age'];
if ($age >= 21) {
echo 'Come on in, we have alcohol and music awaiting you!';
}
else {
echo 'You're too young for this club, come back when you're a little older';
}
}
?>
</body>
</html>
As you can see, the script contains two pages: the initial, empty form and the result page generated after hittingthe submit button. In order to decide which page to display, the script first tests for the presence of the
$_POST['submit'] variable. If it doesn't find it, it assumes that the form has yet to be submitted, and displays
the initial list of days. Once the form has been submitted, the same script will be called to process the forminput. This time, however, the $_POST['submit'] variable will be set, and so PHP will not display the initial
page, but rather the page containing the result message.
Note that for this to work, your submit button must have a value assigned to its "name" attribute, and you must
check for that value in the primary conditional statement. And in case you were wondering, the $_SERVER array
is a special PHP variable which always holds server information, including the path and name of the currentlyexecuting script.
Next up, loops.
One by One
For those of you unfamiliar with the term, a loop is a control structure that enables you to repeat the same setof phpstatements or commands over and over again (the actual number of repetitions can be a number you specify, ordepend on the fulfillment of one or more conditions).
Now, last time out you saw a few comparison and logical operators, which help in building conditionalstatements. Since this segment of the tutorial is going to focus on loops, this is an appropriate time to introduceyou to PHP's auto-increment and auto-decrement operators, which see a lot of use in this context.
The auto-increment operator is a PHP operator designed to automatically increment the value of the variable it isattached to by 1. It is represented by two "plus" signs (++). This snippet of code should explain it:
<?php
// define $total as 10
$total = 10;
// increment it
$total++;
// $total is now 11
echo $total;
?>
Thus, $total++ is functionally equivalent to $total = $total + 1.
There's a corresponding auto-decrement operator (--), which does exactly the opposite:
<?php
// define $total as 10
$total = 10;
// decrement it
$total--;
// $total is now 9echo $total;
?>
These operators are frequently used in loops, to update the value of the loop counter, speaking of which...
Being Square
The first - and simplest - loop to learn in PHP is the so-called while() loop, which looks like this:
while (condition is true) {
do this!
}
In this case, so long as the condition specified evaluates as true - remember what you learned in Part Two? - thePHP statements within the curly braces will continue to execute. As soon as the condition becomes false, theloop will be broken and the statements following it will be executed.
Here's a quick example which demonstrates the while() loop:
<html>
<head></head>
<body>
<form action="squares.php" method="POST">
Print all the squares between 1 and <input type="text" name="limit" size="4" maxlength="4">
<input type="submit" name="submit" value="Go">
</form>
</body>
</html>
This is a simple form which asks the user to enter a number. When the form is submitted, the PHP script that isinvoked should take this number and print the squares of all the numbers between 1 and the entered value.With a while() loop, this is simplicity itself:
<html>
<head></head>
<body>
<?php
// set variables from form input
$upperLimit = $_POST['limit'];
$lowerLimit = 1;
// keep printing squares until lower limit = upper limit
while ($lowerLimit <= $upperLimit) {
echo ($lowerLimit * $lowerLimit).' ';
$lowerLimit++;
}
// print end marker
echo 'END';
?>
</body>
</html>
This script uses a while() loop to count forwards from 1 until the values of $lowerLimit and $upperLimit are
equal.
Loop First, Ask Questions Later
The while() loop executes a set of statements while a specified condition is true. But what happens if the
condition is true on the first iteration of the loop itself? In the previous example, if you were to enter the value0in the form, the while() loop would not execute even once. Try it yourself and you'll see what I mean.
If you're in a situation where you need to execute a set of statements *at least* once, PHP offers you thedo-while() loop. Here's what it looks like:
do {
do this!
} while (condition is true)
Let's take a quick example to better understand the difference between while() and do-while():
<?php
$x = 100;
// while loop
while ($x == 700) {
echo "Running...";
break;
}
?>
In this case, no matter how many times you run this PHP script, you will get no output at all, since the value of$x is not equal to 700. But, if you ran this version of the script:
Both the while() and do-while() loops continue to iterate for as long as the specified conditional expression
remains true. But what if you need to execute a certain set of statements a specific number of times - forexample, printing a series of thirteen sequential numbers, or repeating a particular set of <td> cells five times?
In such cases, clever programmers reach for the for() loop...
The for() loop typically looks like this:
for (initial value of counter; condition; new value of counter) {
do this!
}
Looks like gibberish? Well, hang in there for a minute...the "counter" here is a PHP variable that is initialized to anumeric value, and keeps track of the number of times the loop is executed. Before each execution of the loop,the "condition" is tested. If it evaluates to true, the loop will execute once more and the counter will beappropriately incremented; if it evaluates to false, the loop will be broken and the lines following it will beexecuted instead.
Here's a simple example that demonstrates how this loop can be used:
<html>
<head>
<basefont face="Arial">
</head>
<body>
<?php
// define the number
$number = 13;
// use a for loop to calculate tables for that number
for ($x = 1; $x <= 10; $x++) {
echo "$number x $x = ".($number * $x)."<br />";
}
?>
</body>
</html>
The first thing I've done here is define the number to be used for the multiplication table. I've used 13 here - forno reason other than that it rhymes with "green".
Next, I've constructed a for() loop with $x as the counter variable, initialized it to 1. and specified that the loop
should run no more than 10 times. The auto-increment operator (discussed earlier) automatically increments thecounter by 1 every time the loop is executed. Within the loop, the counter is multiplied by the number, to createthe multiplication table, and echo() is used to display the result on the page.
Turning the Tables
As you just saw, a for() loop is a very interesting - and useful - programming construct. The next example
illustrates its usefulness in a manner that should endear it to any HTML programmer.
As you'll see if you try coding the same thing by hand, PHP's for() loop just saved you a whole lot of work! And
it looks good too - take a look at the source code of the dynamically generated table, and you'll see that it'snicely formatted, with line breaks at the end of every table cell and row. This magic is accomplished by forcing acarriage return with in every call to echo().
For more examples of the for() loop in action, visit http://www.php.net/manual/en/control-structures.for.php.
Loops are frequently used in combination with one of PHP's more complex data types, the animal known as thearray. That's a whole topic in itself, and in fact I'm going to discuss it in detail in the next segment of thistutorial. Then I'm going to show you how arrays, loops and forms all work together to make the creation ofcomplex Web forms as easy as eating pie. All that and more in Part Four!
Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Tuesday, February 6, 2007
GREAT TUTORIAL6:07AM PST � Anonymous User [unregistered]
This is the best tutorial i have ever seen. The table thing was hard but i got through it because this tutorial issoo great
Friday, February 16, 2007
GREAT TUTORIALS7:54PM PST � ben [unregistered]
Hate to parrot everyone else's comments, but I'd like to say how great these tuts are. Thank you for taking thetime to write such concise and intelligent articles. Truly the best I have found so far.
Wednesday, May 2, 2007
CREATIVE CONDITIONALS8:01AM PDT � Anonymous User [unregistered]
These are very great tutorials, very informative, especially for the beginner user! Just wanted to make a note,I'm not sure if everyone ran into this problem, but when doing the Creative Conditionals section of the tut, the browser had trouble parsing this line:
echo 'You're too young for this club, come back when you're a little older';
It worked if I took out the apostrophe's in your're. Just wanted to let anyone know that ran into this problem.
Thanks for the great tutorials!!!
Saturday, May 5, 2007
TURNING THE TABLES3:30PM PDT � Anonymous User [unregistered]
You forgot to include the 's and 's to make the source code 'neat.'
Try this instead:
<html><head></head><body><form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">Enter number of rows <input name="rows" type="text" size="4"> and columns <input name="columns" type="text" size="4"> <input type="submit" name="submit" value="Draw Table"></form>
TURNING THE TABLES3:36PM PDT � Anonymous User [unregistered]
Oh vey. I tried to include backslash t " " and backslash n " " but they disappeared from my post. They'rerequired in the code to include the tabs and newlines that keep the source code neat and pretty.
by Vikram Vaswani | 3 comments | Tuesday, July 20, 2004
A Big MistakeFruity PizzaEating ItalianPush And PullLooping the LoopWhat's That Noise?Music for the Masses
A Big Mistake
Having spent lots of time travelling around the outer landscape of PHP - learning all about control structures,operators and variables - you're probably bored. You might even be thinking of dropping out right now, andinstead spending your time more constructively (or so you think) in front of the idiot box.
That would be a big mistake. And when I say big, I mean humongous.
You see, if you forego this segment of the tutorial for the dubious charms of Ally McBeal, you're going to missout on one of PHP's coolest variable types. It's a little thing called an array, and I'm not exaggerating when I tellyou that once you're on speaking terms with it, you're never going to look at a PHP script the same way again.But hey, don't take my word for it... toss that remote aside and come see for yourself!
Fruity Pizza
Thus far, the variables we've discussed contained only a single value, such as:
<?php
$i = 5;
?>
However, array variables are a different kettle of fish altogether. An array is a complex variable that allows youto store multiple values in a single variable (which is handy when you need to store and represent relatedinformation). Think of the array variable as a "container" variable, which can contain one or more values. Forexample:
Here, $pizzaToppings is an array variable, which contains the values 'onion', 'tomato', 'cheese',
'anchovies', 'ham' and 'pepperoni'. (Array variables are particularly useful for grouping related values
together.)
print_r() is a special function that allows you to take a sneak peek inside an array. It's more useful for
debugging (finding out why your script doesn't work) than it is for display purposes, but I'll use it here so youcan see what's going on under the surface. You do have your server running and your browser open, right?
The various elements of the array are accessed via an index number, with the first element starting at zero. So,to access the element 'onion', you would use the notation $pizzaToppings[0], while 'anchovies' would be
$pizzaToppings[3] - essentially, the array variable name followed by the index number enclosed within square
braces.
PHP also allows you to replace indices with user-defined "keys", in order to create a slightly different type ofarray. Each key is unique, and corresponds to a single value within the array.
In this case, $fruits is an array variable containing four key-value pairs. (The => symbol is used to indicate the
association between a key and its value.) In order to access the value 'banana', you would use the notation
$fruits['yellow'], while the value 'grape' would be accessible via the notation $fruits['green'].
This type of array is sometimes referred to as a "hash" or "associative array". If you've ever used Perl, you'll seethe similarities to the Perl hash variable.
Eating Italian
The simplest was to define an array variable is the array() function. Here's how:
<?php
// define an array$pasta = array('spaghetti', 'penne', 'macaroni');
?>
The rules for choosing an array variable name are the same as those for any other PHP variable: it must beginwith a letter or underscore, and can optionally be followed by more letters, numbers and underscores.
Alternatively, you can define an array by specifying values for each element in the index notation, like this:
<?php
// define an array
$pasta[0] = 'spaghetti';
$pasta[1] = 'penne';
$pasta[2] = 'macaroni';
?>
If you're someone who prefers to use keys rather than default numeric indices, you might prefer the followingexample:
<?php
// define an array
$menu['breakfast'] = 'bacon and eggs';
$menu['lunch'] = 'roast beef';
$menu['dinner'] = 'lasagna';
?>
You can add elements to the array in a similar manner. For example, if you wanted to add the element 'green
olives' to the $pizzaToppings array, you would use something like this:
<?php
// add an element to an array
$pizzaToppings[3] = 'green olives';
?>
In order to modify an element of an array, simply assign a new value to the corresponding scalar variable. If youwanted to replace 'ham' with 'chicken', you'd use:
<?php
// modify an array
$pizzaToppings[4] = 'chicken';
?>
You can do the same using keys. The following statement modifies the element with the key 'lunch' to adifferent value:
<?php
// modify an array
$menu['lunch'] = 'steak with mashed potatoes';
?>
Push And Pull
You can also add an element to the end of an existing array with the array_push() function:
<?php
// define an array
$pasta = array('spaghetti', 'penne', 'macaroni');
// add an element to the end
array_push($pasta, 'tagliatelle');
print_r($pasta);
?>
And you can remove an element from the end of an array using the interestingly-named array_pop() function.
<?php
// define an array
$pasta = array('spaghetti', 'penne', 'macaroni');
// remove an element from the end array_pop($pasta);
print_r($pasta);
?>
If you need to pop an element off the top of the array, you can use the array_shift() function:
<?php
// define an array
$pasta = array('spaghetti', 'penne', 'macaroni');
// take an element off the top
array_shift($pasta);
print_r($pasta);
?>
And the array_unshift() function takes care of adding elements to the beginning of the array.
<?php
// define an array
$pasta = array('spaghetti', 'penne', 'macaroni');
// add an element to the beginning
array_unshift($pasta, 'tagliatelle');
print_r($pasta);
?>
The array_push() and array_unshift() functions don't work with associative arrays; to add elements to these
arrays, it's better to use the $arr[$key] = $value notation to add new values to the array.
The explode() function splits a string into smaller components, based on a user-specified delimiter, and returns
the pieces as elements as an array.
<?php
// define CSV string
$str = 'red, blue, green, yellow';
// split into individual words
$colors = explode(', ', $str);
print_r($colors);
?>
To do the reverse, you can use the implode() function, which creates a single string from all the elements of an
array by joining them together with a user-defined delimiter. Reversing the example above, we have:
Finally, the two examples below show how the sort() and rsort()functions can be used to sort an array
alphabetically (or numerically), in ascending and descending order respectively:
<?php
// define an array
$pasta = array('spaghetti', 'penne', 'macaroni');
// returns the array sorted alphabetically
sort($pasta);
print_r($pasta);
print "<br />";
// returns the array sorted alphabetically in reverse rsort($pasta); print_r($pasta);
?>
Looping the Loop
So that takes care of putting data inside an array. Now, how about getting it out?
Retrieving data from an array is pretty simple: all you need to do is access the appropriate element of the arrayusing its index number. To read an entire array you simply loop over it, using any of the loop constructs youlearned about in Part Three of this tutorial.
How about a quick example?
<html>
<head></head>
<body>
My favourite bands are:
<ul>
<?php
// define array
$artists = array('Metallica', 'Evanescence', 'Linkin Park', 'Guns n Roses');
// loop over it and print array elements
for ($x = 0; $x < sizeof($artists); $x++) {
echo '<li>'.$artists[$x];
}
?>
</ul>
</body>
</html>
When you run this script, here's what you'll see:
My favourite bands are:
Metallica
Evanescence
Linkin Park
Guns n Roses
In this case, I've defined an array, and then used the for() loop to: run through it, extract the elements using
the index notation, and display them one after the other.
I'll draw your attention here to the sizeof() function. This function is one of the most important and commonly
used array functions. It returns the size of (read: number of elements within) the array. It is mostly used in loopcounters to ensure that the loop iterates as many times as there are elements in the array.
If you're using an associative array, the array_keys() and array_values()functions come in handy, to get a
/* returns the array ('breakfast', 'lunch', 'dinner') with numeric indices */
$result = array_keys($menu);
print_r($result);
print "<br />";
/* returns the array ('bacon and eggs', 'roast beef', 'lasagna') with numeric indices */
$result = array_values($menu);
print_r($result);
?>
What's That Noise?
There is, however, a simpler way of extracting all the elements of an array. PHP 4.0 introduced a spanking-newloop type designed specifically for the purpose of iterating over an array: the foreach() loop. (It is similar in
syntax to the Perl construct of the same name.) Here's what it looks like:
foreach ($array as $temp) {
do this!
}
A foreach() loop runs once for each element of the array passed to it as argument, moving forward through the
array on each iteration. Unlike a for() loop, it doesn't need a counter or a call to sizeof(), because it keeps
track of its position in the array automatically. On each run, the statements within the curly braces areexecuted, and the currently-selected array element is made available through a temporary loop variable.
To better understand how this works, consider this rewrite of the previous example, using the foreach() loop:
<html>
<head></head>
<body>
My favourite bands are:
<ul>
<?php
// define array
$artists = array('Metallica', 'Evanescence', 'Linkin Park', 'Guns n Roses');
// loop over it
// print array elements
foreach ($artists as $a) {
echo '<li>'.$a;
}
?>
</ul>
</body>
</html>
Each time the loop executes, it places the currently-selected array element in the temporary variable $a. This
variable can then be used by the statements inside the loop block. Since a foreach() loop doesn't need a
counter to keep track of where it is in the array, it is lower-maintenance and also much easier to read than astandard for() loop. Oh yeah... and it also works with associative arrays, with no extra programming needed.
Music for the Masses
In addition to their obvious uses, arrays and loops also come in handy when processing forms in PHP. Forexample, if you have a group of related checkboxes or a multi-select list, you can use an array to capture all theselected form values in a single variable, to simplify processing. Consider the following example, whichillustrates this:
// use a foreach loop to read and display array elements
if (is_array($_POST['artist'])) {
echo 'You selected: <br />';
foreach ($_POST['artist'] as $a) {
echo "<i>$a</i><br />";
}
}
else {
echo 'Nothing selected';
}
}
?>
</body>
</html>
When the above form is submitted, PHP will automatically create an array variable, and populate it with theitems selected. This array can then be processed with a foreach() loop, and the selected items retrieved from
it.
You can do this with a multi-select list also, simply by using array notation in the select control's "name"attribute. Try it out for yourself and see... and make sure you tune in for the next PHP 101 tutorial, same time, same channel.
Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Friday, August 4, 2006
Q12:26AM PDT � zarezadeh
what about we want to add an element from an associative array with array_push?
Tuesday, September 5, 2006
ADDING TO AN ASSOCIATIVE ARRAY8:56PM PDT � phmThePhpNewbie
I've just tried as I think the simpler way is this one :<?php // define an array$menu = array('breakfast' => 'bacon and eggs', 'lunch' => 'roast beef', 'dinner' => 'lasagna'); // add an element to the end $menu['midnight meal']='whisky';print_r($menu); ?>
//array_push($menu, 'midnight meal' => 'whisky'); just dont work
Wednesday, September 27, 2006
OR ANOTHER WAY OF PUTTING IT....4:38AM PDT � Anonymous User [unregistered]
by Vikram Vaswani | 9 comments | Wednesday, July 21, 2004
Back to SchoolHandle With Care• Open the file and assign it a file handle• Interact with the file via its handle and extract its contents into a PHP variable• Close the fileDifferent StrokesWhen Laziness is a VirtueWriting to MaInformation is PowerBreaking Eggs
Back to School
When you first started reading this series, I promised you that you'd have a whole lot of fun. If you're thecynical type, you may be feeling that I didn't keep my promise. After all, how much fun have you really had so far? All you've done is learn a bunch of theoretical rules, added and subtracted numbers from each other, learntprimitive decision-making and gone round and round in the circular funhouse of loops. Heck, if this wasn't a PHPtutorial, it would be kindergarten...
I hear you.
In this segment of our ongoing saga, I'm going to teach you how to do something that's definitely not for kids. Itinvolves getting down and dirty with files on the disk: meeting them (shock!), reading their contents (shriek!)and (horror of horrors!) writing data to them. All of these exciting activities will take place under the aegis ofPHP's very cool file manipulation API, which allows you to view and modify file attributes, read and list directorycontents, alter file permissions, retrieve file contents into a variety of native data structures, and search for filesbased on specific patterns.
Let's get started!
Handle With Care
I'll begin with something simple: opening a file and reading its contents. Let's assume that somewhere on yourdisk, hidden under /usr/local/stuff/that/should/be/elsewhere/recipes/, you have a text file containing the recipefor the perfect Spanish omelette. You now wish to read the contents of this file into a PHP script.
In order to do this, there are three distinct steps to be followed:
Open the file and assign it a file handle.Interact with the file, via its handle, and extract its contents into a PHP variable.Close the file.Here's a PHP script that does just that:
<?php
// set file to read
$file = '/usr/local/stuff/that/should/be/elsewhere/recipes/omelette.txt' or die('Could not open
file!');
// open file
$fh = fopen($file, 'r') or die('Could not open file!');
// read file contents
$data = fread($fh, filesize($file)) or die('Could not read file!');
// close file
fclose($fh);
// print file contents
echo $data;
?>
Run this script through your Web browser, and PHP should return the contents of the file.
Now let me explain each of the three steps above in detail:
Open the file and assign it a file handle
PHP needs a file handle to read data from a file. This file handle can be created with the fopen() function, which
accepts two arguments: the name and path to the file, and a string indicating the "mode" in which the file is tobe opened ('r' for read).
Three different modes are available for use with the fopen() function. Here's the list:
'r' - opens a file in read mode
'w' - opens a file in write mode, destroying existing file contents
'a' - opens a file in append mode, preserving existing file contents
Interact with the file via its handle and extract its contents into a PHP variable
If the fopen() function is successful, it returns a file handle, $fh, which can be used for further interaction with
the file. This file handle is used by the fread() function, which reads the file and places its contents into a
variable.
The second argument to fread() is the number of bytes to be read. You can usually obtain this information
through the filesize() function, which - who'd have guessed it?!- returns the size of the file in bytes.
Close the file
This last step is not strictly necessary as PHP closes the file automatically once it reaches the end of the script,
but it's a good habit to develop. Explicitly closing the file with fclose() has two advantages: it ties up loose
ends in your script, and it wins you lots of good karma from the PHP community.
You probably haven't see the die() function before, either. This function is mostly used as a primitive
error-handling mechanism. In the event of a fatal error, such as the file path being invalid or the file permissionsbeing such that PHP cannot read it, die() terminates script processing and optionally displays a user-specified
error message indicating why it committed suicide.
Different Strokes
An alternative method of reading data from a file is the very cool file() function, which reads the entire file
into an array (remember them?) with one line of code. Each element of the array then contains one line from thefile. To display the contents of the file, simply iterate over the array in a foreach() loop and print each element.
The following example demonstrates:
<?php
// set file to read
$file = '/usr/local/stuff/that/should/be/elsewhere/recipes/omelette.txt' or die('Could not read
file!');
// read file into array
$data = file($file) or die('Could not read file!');
// loop through array and print each line
foreach ($data as $line) {
echo $line;
}
?>
In this example, the file() command opens the file, reads it into an array and closes the file - all in one, single,
elegant movement. Each element of the array now corresponds to a line from the file. It's easy to print the file'scontents now - just reach for that mainstay of array processing, the foreach() loop.
Don't want the data in an array? Try the file_get_contents() function, new in PHP 4.3.0 and PHP 5.0, which
$data = file_get_contents($file) or die('Could not read file!');
// print contents
echo $data;
?>
Who am I kidding? I always use the one-line functions noted above instead of the three-line sequence offopen(), fread() and fclose(). Laziness conquers all.
When Laziness is a Virtue
PHP also offers two very useful functions to import files into a PHP script: the include() and
require()functions. These functions can be used to suck external files lock, stock and barrel into a PHP script,
which is very handy if, for example, you have a modular application which has its code broken down across filesin separate locations.
The best way to understand the utility of the include() and require() functions is with an example. Assume
that on your Web site you have a standard menu bar at the top of every page, and a standard copyright noticein the bottom. Instead of copying and pasting the header and footer code on each individual page, PHP gurussimply create separate files for the header and footer, and import them at the top and bottom of each script.This also makes a change to the site design easier to implement: instead of manually editing a gazillion files,you simply edit two, and the changes are reflected across your entire site instantaneously.
Let's see a real live example of this in action. Create the header in one file, called header.php:
Next, create the footer with the copyright notice in a second file, footer.php:
<!-- footer begins -->
<br /><center>Your usage of this site is subject to its published <a href="tac.html">terms and conditions</a>. Data is copyright Big Company Inc, 1995-<?php echo date("Y", mktime()); ?></center> </body> </html>
Finally, create a script to display the main content of your site, and include() the header and footer at
appropriate places:
<?php
// create an array to set page-level variables
$page = array();
$page['title'] = 'Product Catalog';
/* once the file is imported, the variables set above will become available to it */
// include the page header
include('header.php');
?>
<!-- HTML content here -->
<?php
// include the page footer
include('footer.php');
?>
Now, when you run the script above, PHP will automatically read in the header and footer files, merge them withthe HTML content, and display the complete page to you. Simple, isn't it?
Notice that you can even write PHP code inside the files being imported. When the file is first read in, the parserwill look for <?php...?> tags, and automatically execute the code inside it. (If you're familiar with JavaScript,
you can use this feature to replicate functionality similar to that of the onLoad() page event handler in
JavaScript.)
PHP also offers the require_once() and include_once()functions, which ensure that a file which has already
been read is not read again. This can come in handy if you have a situation in which you want to eliminatemultiple reads of the same include file, either for performance reasons or to avoid corruption of the variablespace.
A quick note on the difference between the include() and require()functions: the require()function returns
a fatal error if the named file cannot be found and halts script processing, while the include() function returns
a warning but allows script processing to continue.
Writing to Ma
After everything you've just read, you've probably realized that reading a file is not exactly brain surgery. Solet's proceed to something slightly more difficult - writing to a file.
The steps involved in writing data to a file are almost identical to those involved in reading it: open the file andobtain a file handle, use the file handle to write data to it, and close the file. There are two differences: first, youmust fopen() the file in write mode ('w' for write), and second, instead of using the fread() function to read
from the file handle, use the fwrite() function to write to it. Take a look:
<?php
// set file to write
$file = '/tmp/dump.txt';
// open file
$fh = fopen($file, 'w') or die('Could not open file!');
// write to file
fwrite($fh, "Look, Ma, I wrote a file! ") or die('Could not write to file');
// close file
fclose($fh);
?>
When you run this script, it should create a file named dump.txt in /tmp, and write a line of text to it, with a
carriage return at the end. Notice that double quotes are needed to convert into a carriage return.
The fopen(), fwrite() and fread() functions are all binary-safe, which means you can use them on binary
files without worrying about damage to the file contents. Read more about many of the issues related tobinary-safe file manipulation on different platforms at http://www.php.net/manual/en/function.fopen.php.
If I've spoiled you by showing you the one-line shortcut functions for file reads, let me damage you further byintroducing you to the file_put_contents() function, new in PHP 5.0, which takes a string and writes it to a
file in a single line of code.
<?php
// set file to write
$filename = '/tmp/dump.txt';
// write to file
file_put_contents($filename, "Look, Ma, I wrote a file! ") or die('Could not write to file');
?>
Bear in mind that the directory in which you're trying to create the file must exist before you can write to it.Forgetting this important step is a common cause of script errors.
Information is Power
PHP also comes with a bunch of functions that allow you to test the status of a file - for example to find outwhether it exists, whether it's empty, whether it's readable or writable, and whether it's a binary or text file. Ofthese, the most commonly used operator is the file_exists() function, which is used to test for the existence
of a specific file.
Here's an example which asks the user to enter the path to a file in a Web form, and then returns a messagedisplaying whether or not the file exists:
There are many more such functions. Here's a brief list, followed by an example that builds on the previous oneto provide more information on the file specified by the user.
is_dir() - returns a Boolean indicating whether the specified path is a directory
is_file() - returns a Boolean indicating whether the specified file is a regular file
is_link() - returns a Boolean indicating whether the specified file is a symbolic link
is_executable() - returns a Boolean indicating whether the specified file is executable
is_readable()- returns a Boolean indicating whether the specified file is readable
is_writable()- returns a Boolean indicating whether the specified file is writable
filesize() - gets size of file
filemtime() - gets last modification time of file
filamtime() - gets last access time of file
fileowner() - gets file owner
filegroup() - gets file group
fileperms() - gets file permissions
filetype() - gets file type
This script asks for a file name as input and uses the functions above to return information on it.
<html>
<head>
</head>
<body>
<?php
/* if form has not yet been submitted, display input box */
/* check if file exists and display appropriate message */
if (file_exists($_POST['file'])) {
// print file size
echo 'File size: '.filesize($_POST['file']).' bytes<br />'; // print file owner echo 'File owner: '.fileowner($_POST['file']).'<br />'; // print file group echo 'File group: '.filegroup($_POST['file']).'<br />'; // print file permissions echo 'File permissions: '.fileperms($_POST['file']).'<br />'; // print file type echo 'File type: '.filetype($_POST['file']).'<br />'; // print file last access time echo 'File last accessed on: '.date('Y-m-d', fileatime($_POST['file'])).'<br />'; // print file last modification time echo 'File last modified on: '.date('Y-m-d', filemtime($_POST['file'])).'<br />'; // is it a directory? if (is_dir($_POST['file'])) { echo 'File is a directory <br />'; } // is it a file? if (is_file($_POST['file'])) { echo 'File is a regular file <br />'; } // is it a link? if (is_link($_POST['file'])) { echo 'File is a symbolic link <br />'; } // is it executable? if (is_executable($_POST['file'])) { echo 'File is executable <br />'; } // is it readable? if (is_readable($_POST['file'])) { echo 'File is readable <br />'; } // is it writable? if (is_writable($_POST['file'])) { echo 'File is writable <br />'; } } else { echo 'File does not exist! <br />'; } } ?>
</body> </html>
And here's what the output might look like:
Breaking Eggs
So now you know how to read a file, write to it, and test its status. Let's look at some examples of what you cando with this new-found power.
Let's go back to my Spanish omelette recipe. Let's suppose I'm feeling generous, and I decide that I'd like tohear what people really think about my culinary skills. Since I have a bunch of recipes that I'd like to share withpeople, and since they all look something like this:
I need a quick way to convert them all into HTML so that they look presentable on my Web site. We've alreadyestablished that I'm lazy, so fuggedaboutme re-creating the recipes in HTML. Instead, I'll have PHP do the heavylifting for me:
<html>
<head></head>
<body>
<?php
// read recipe file into array
$data = file('/usr/local/stuff/that/should/be/elsewhere/omelette.txt') or die('Could not read
file!');
/* first line contains title: read it into variable */
$title = $data[0];
// remove first line from array
array_shift($data);
?>
File name: /usr/local/apache/logs/error_logFile size: 53898 bytesFile owner: 0File group: 0File permissions: 33188File type: fileFile last accessed on: 2004-05-26File last modified on: 2004-06-20File is a regular fileFile is readable
SPANISH OMELETTEINGREDIENTS:- 1 chopped onion- 1 chopped tomato- 1/2 chopped green pepper- 4 beaten eggs- Salt and pepper to tasteMETHOD:1. Fry onions in a pan2. Pour beaten eggs over onions and fry gently3. Add tomatoes, green pepper, salt and pepper to taste4. Serve with toast or bread
<h2><?php echo $title; ?></h2>
<?php /* iterate over content and print it */ foreach ($data as $line) { echo nl2br($line); } ?>
</body> </html>
I've used the file() function to read the recipe into an array, and assign the first line (the title) to a variable.
That title is then printed at the top of the page. Since the rest of the data is fairly presentable as is, I can simplyprint the lines to the screen one after the other. Line breaks are automatically handled for me by the extremelycool nl2br() function, which converts regular text linebreaks into the HTML equivalent, the <br /> tag. The end
result: an HTML-ized version of my recipe that the world can marvel at. Take a look:
If the elegance and creative simplicity of my Spanish omelette recipe has left you speechless, I'm not surprised -many people feel that way. Until you get your voice back: Ciao... and make sure you come back to work throughPart Six of PHP 101, which discusses creating your own reusable functions.
Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Monday, August 21, 2006
KELVIN9:18PM PDT � Anonymous User [unregistered]
Interesting, I've seen some people put the egg in last.
Thursday, August 24, 2006
THE INCLUDE PART OF THIS3:34PM PDT � mike [unregistered]
// include the page header include('header.php');
I have two quick questions on this one little thing up there.. if anyone answers, thanks!
Does anyone know how to shut off the error message if it cant find the file?And is there a good way to get it to look at the start of the domain or a specific folder each time without havingto put this http://www.somedomain.com part? ('http://www.somedomain.com/header.php');
Monday, September 4, 2006
TWO QUICK ANSWERS5:51AM PDT � heymcd
> Does anyone know how to shut off the error message if it cant find the file?
error_reporting in php.ini
> And is there a good way to get it to look at the start of the domain or a specific folder each time without having to put this http://www.somedomain.com part? ('http://www.somedomain.com/header.php');
/header.php will find the file in root of your site /includes/header.php will find the file in the /includes directory of your site
Wednesday, September 6, 2006
ANOTHER SHORT ANWSER1:51AM PDT � k038i [unregistered]
If you don't want to turn all error-messages off (that's what heymcd's proposition would do) you could insteadset a '@' in front of the include function.
- Salt and pepper to taste<br />METHOD:<br />1. Fry onions in a pan<br />2. Pour beaten eggs over onions and fry gently<br />3. Add tomatoes, green pepper, salt and pepper to taste<br />4. Serve with toast or bread<br />
</body></html>
?>
Thursday, October 5, 2006
TO MAKE THINGS MORE CLEAR FOR NEWCOMERS...3:07PM PDT � Ivan Aleman bonovoxmofo (at) gmail dot com [unregistered]
Hello,
On your first example on this page you maybe want to enhance the script combining things used in early scripts, like this:
<?php
// set file to read$file = '/home/ivan/open_sesame.txt';// open file$fh = fopen($file, 'r') or die('Could not open file!');// read file contents$data = fread($fh, filesize($file)) or die('Could not read file!');// close filefclose($fh);// print file contents$data_ord = explode("\n", $data);print_r($data_ord);
?>
And for the second example someone maybe want to try this one a little bit modified:
<?php
// set file to read$file = '/home/ivan/open_sesame.txt';
// read file into array$data = file($file) or die('Could not read file!');
// loop through array and print each lineforeach ($data as $line) {echo $line."<br />";}
?>
Good material and also is fun to read it.
Thanks.
Monday, November 13, 2006
I FOUND A MISTAKE!11:21AM PST � Red [unregistered]
Look at the next two lines:
filemtime() - gets last modification time of filefilemtime() - gets last access time of file
The first line is correct, but the second one should read:
fileatime() - gets last access time of file
Just thought you ought to know...
--Red
Tuesday, April 3, 2007
FIXED6:16AM PDT � Cal Evans (editor)
Thanks, I’ve made the correction.
=C=
Friday, April 13, 2007
DOESN'T WORK RIGHT FOR ME2:09PM PDT � Anonymous User [unregistered]
I've tried using this, but I can't seem to get it to work! I changed the die message to try to figure out what waswrong:
<?php
$file = '/test/test.txt' or die ('Could not open file');
$fh = fopen($file, 'r') or die('Could not open the file!');
$data = fread($fh, filesize($file)) or die('Could not read that file');
fclose($fh);
echo $data;
?>
I'm getting this output:
Could not open the file!
so I'm assuming it can find the file, but for some reason can't open it. This isn't a good start for me :p
Tuesday, May 29, 2007
RESPONSE TO PREVIOUS COMMENT9:56AM PDT � Anonymous User [unregistered]
That first die function shouldn't be there. All that line does is assign the filepath as a string to the $file variable.The filepath is not checked at that point. Since the assignment doesn't fail, the die() function is not invoked. The following file operation is where we discover that the filepath is actually invalid, so the second die() function is called.
by Vikram Vaswani | 3 comments | Saturday, August 7, 2004
A Little KnowledgeIn Plain EnglishMonday Morning BluesHaving an Argument... or TwoCircles in the SandMarching OrderThe Amazing Shrinking Argument ListGoing GlobalChecking References
A Little Knowledge
If you've been taking your regular dose of PHP 101, you know now enough about PHP to write simple programsof your own. However, these programs will be "procedural" or linear - the statements in them will be executedsequentially, one after another - simply because that's the only programming style I've used so far.
You know what they say about a little knowledge being a dangerous thing... as your PHP scripts become moreand more complex, it's only a matter of time before you bump your head against the constraints of theprocedural method, and begin looking for a more efficient way of structuring your PHP programs.
That's where Part Six of PHP 101 comes in. In this tutorial I'm going to introduce you to a new way of doingthings, where code doesn't run in a straight line, but twists, leaps and bounds across the landscape of yourscript. Most of this activity is accomplished through a programming construct called a "function", and thistutorial teaches you how to build them (once), use them (many times), pass them arguments and have themreturn values, and generally make your scripts more compact, efficient and maintainable.
In Plain English
Ask a geek to define the term "function", and he'll probably mumble something about a function being "a blockof statements that can be grouped together as a named entity." Since this is a tutorial on PHP, not anintroductory course in Greek, I'll translate that for you: a function is simply a set of program statements whichperform a specific task, and which can be "called", or executed, from anywhere in your program.
Every programming language comes with its own built-in functions, and typically also allows developers todefine their own functions. For example, if I had a profit statement for the year on my desk, and I wanted toinflate each number by 35%, I could call my neighborhood accounting firm and get them to do it for me... or Icould write a simple PHP function called cheatTheShareholders() and have it do the work for me (it's faster,
plus PHP doesn't bill by the hour).
There are three important reasons why functions are a Good Thing™. First: user-defined functions allow you toseparate your code into easily identifiable subsections - which are easier to understand and debug. Second:functions make your program modular, allowing you to write a piece of code once and then re-use it multipletimes within the same program. And third: functions simplify code updates or changes, because the changeneeds only to be implemented in a single place (the function definition). Functions thus save time, money andelectrons... and I know the electrons at least will thank you!
Monday Morning Blues
To see how a function works, look at the following example:
<?php
// define a function
function myStandardResponse() {
echo "Get lost, jerk!<br /><br />";
}
// on the bus
echo "Hey lady, can you spare a dime? <br />";
myStandardResponse();
// at the office
echo "Can you handle Joe's workload, in addition to your own, while he's in Tahiti for a month?
You'll probably need to come in early and work till midnight, but we are confident you can
handle it. Oh, and we can't pay you extra because of budgetary constraints...<br />";
myStandardResponse();
// at the party
echo "Hi, haven't I seen you somewhere before?<br />";
myStandardResponse();
?>
Here's what the output might look like:
(Sure it's rude, but it does demonstrate how a function allows you to reuse pieces of code.)The first thing I've done in the script above is define a new function, with the function keyword. This keyword
is followed by the name of the function, which in this case is myStandardResponse(). All the program code
attached to that function is then placed within a pair of curly braces - and this program code can contain loops,conditional statements, calls to other user-defined functions, or calls to other PHP functions.
Hey lady, can you spare a dime?Get lost, jerk!
Can you handle Joe's workload, in addition to your own, while he's in Tahiti for a month?You'll probably need to come in early and work till midnight, but we are confident you canhandle it. Oh, and we can't pay you extra because of budgetary constraints...Get lost, jerk!
Hi, haven't I seen you somewhere before?Get lost, jerk!
Of course, defining a function is only half of the puzzle; for it to be of any use at all, you need to "invoke" it. InPHP, as in a million other languages, this is accomplished by calling the function by its name, as I've done in theexample above. Calling a user-defined function is identical to calling a built-in PHP function like echo() or
explode().
Here's the typical format for a function:
function function_name (optional function arguments) {
statement 1...
statement 2...
.
.
.
statement n...
}
Having an Argument... or Two
Functions like the one you saw in the previous section print the same value every time you invoke them. Whilethis is interesting the first six times, it can get boring on the seventh. What we need to do, to make theseboring, unintelligent functions a little more exciting, is get them to return a different value each time they areinvoked.
Enter arguments.
Arguments work by using a placeholder to represent a certain variable within a function. Values for this variableare provided to the function at run-time from the main program. Since the input to the function will differ ateach invocation, so will the output.
To see how this works, look at the following function, which accepts a single argument and then prints it backafter a calculation:
<?php
// define a function
function getCircumference($radius) {
echo "Circumference of a circle with radius $radius is ".sprintf("%4.2f", (2 * $radius *
pi()))."<br />";
}
// call a function with an argument
getCircumference(10);
// call the same function with another argument
getCircumference(20);
?>
In this example, when the getCircumference() function is called with an argument, the argument is assigned
to the placeholder variable $radius within the function, and then acted upon by the code within the function
definition.
It's also possible to pass more than one argument to a function. This is done using a comma-separated list, asthe following example shows:
<?php
// define a function
function changeCase($str, $flag) {
/* check the flag variable and branch the code */
switch($flag) {
case 'U':
print strtoupper($str)."<br />";
break;
case 'L':
print strtolower($str)."<br />";
break;
default:
print $str."<br />";
break;
}
}
// call the function
changeCase("The cow jumped over the moon", "U");
changeCase("Hello Sam", "L");
?>
Here, depending on the value of the second argument, program flow within the function moves to theappropriate branch and manipulates the first argument.
Note that there is no requirement to specify the data type of the argument being passed to a function. SincePHP is a dynamically-typed language, it automatically identifies the variable type and acts on it appropriately.
Circles in the Sand
The functions on the previous page simply printed their output to the screen. But what if you want the functionto do something else with the result? Well, in PHP, you can have a function return a value, such as the result ofa calculation, to the statement that called it. This is done using a return statement within the function, as
shown below:
<?php
// define a function
function getCircumference($radius) {
// return value
return (2 * $radius * pi());
}
/* call a function with an argument and store the result in a variable */
$result = getCircumference(10);
/* call the same function with another argument and print the return value */
print getCircumference(20);
?>
Here, the argument passed to the getCircumference() function is processed, and the result is returned to the
main program, where it may be captured in a variable, printed, or dealt with in other ways.
You can even use the result of a function inside another function, as illustrated in this minor revision of theexample above:
<?php
// define a function
function getCircumference($radius) {
// return value
return (2 * $radius * pi());
}
// print the return value after formatting it
print "The answer is ".sprintf("%4.2f", getCircumference(20));
?>
Return values need not be numbers or strings alone: a function can just as easily return an array (rememberthem?), as demonstrated in the following example:
<?php
/* define a function that can accept a list of email addresses */
function getUniqueDomains($list) {
/* iterate over the list, split addresses and add domain part to another array */
$domains = array();
foreach ($list as $l) {
$arr = explode("@", $l);
$domains[] = trim($arr[1]);
}
// remove duplicates and return
return array_unique($domains);
}
// read email addresses from a file into an array
$fileContents = file("data.txt");
/* pass the file contents to the function and retrieve the result array */
$returnArray = getUniqueDomains($fileContents);
// process the return array
foreach ($returnArray as $d) {
print "$d, ";
}
?>
Assuming the file looked like this,
the output of the script above would look like this:
Note that the return statement terminates program execution inside a function.
Marching Order
The order in which arguments are passed to a function can be important. The following example requires thatthe name is passed as the first argument, and the place as the second.
In this example, if you reversed the order in which arguments were passed to the function, this is what you'dsee:
And look what happens if you forget to pass a required argument altogether:
In order to avoid such errors, PHP allows you to specify default values for all the arguments in a user-definedfunction. These default values are used if the function invocation is missing some arguments. Here's anexample:<?php
// define a function
function introduce($name="John Doe", $place="London") {
print "Hello, I am $name from $place";
}
// call function
introduce("Moonface");
?>
In this case the output would be:
Notice that the function has been called with only a single argument, even though the function definitionrequires two. However, since default values are present for each argument in the function, the missingargument is replaced by the default value for that argument, and no error is generated.
The Amazing Shrinking Argument List
All the examples on the previous page have one thing in common: the number of arguments in the functiondefinition is fixed. However, PHP 4.x also supports variable-length argument lists, by using thefunc_num_args() and func_get_args() commands. For want of a better name, these functions are called
"function functions". Try wrapping your tongue around that while you look at the next example, whichdemonstrates how they can be used:
<?php
// define a function
function someFunc() {
// get the arguments
$args = func_get_args();
// print the arguments
print "You sent me the following arguments:";
foreach ($args as $arg) {
print " $arg ";
}
print "<br />";
}
// call a function with different arguments
someFunc("red", "green", "blue");
someFunc(1, "soap");
?>
Hmmm... if you're sneaky, you might have tried to pass someFunc() an array, and found that instead of
displaying the elements of the array, it simply said "Array". You can fix this by adding a quick test for arrayarguments inside the function, as in this rewrite:
<?php
// define a function
function someFunc() {
// get the number of arguments passed
$numArgs = func_num_args();
// get the arguments
$args = func_get_args();
// print the arguments
print "You sent me the following arguments: ";
for ($x = 0; $x < $numArgs; $x++) {
print "<br />Argument $x: ";
/* check if an array was passed and, if so, iterate and print contents */
if (is_array($args[$x])) {
print " ARRAY ";
foreach ($args[$x] as $index => $element) {
print " $index => $element ";
}
}
else {
print " $args[$x] ";
}
}
Hello, I am Moonface from The Faraway Tree
Hello, I am The Faraway Tree from Moonface
Warning: Missing argument 2 for introduce() in xx.php on line 3Hello, I am Moonface from
Hello, I am Moonface from London
}
// call a function with different arguments someFunc("red", "green", "blue", array(4,5), "yellow");
?>
Going Global
Let's now talk a little bit about the variables used within a function, and their relationship with variables in theoutside world. Usually, the variables used within a function are "local" - meaning that the values assigned tothem, and the changes made to them, are restricted to the function space alone.
Consider this simple example:
<?php
// define a variable in the main program
$today = "Tuesday";
// define a function
function getDay() {
// define a variable inside the function
$today = "Saturday";
// print the variable
print "It is $today inside the function<br />";
}
// call the function
getDay();
// print the variable
print "It is $today outside the function";
?>
When you run this script, here is what you will see:
In other words, the variable inside the function is insulated from the identically-named variable in the mainprogram. Variables inside a function are thus aptly called "local" variables because they only exist within thefunction in which they are defined.The reverse is also true: variables defined inside a function cannot be "seen" outside it. To illustrate, take a lookat the next example and its output (or the lack of it):
<?php
// define a function
function getDay() {
// define a variable inside the function
$today = "Saturday";
}
getDay();
print "Today is $today";
?>
Here is the output:
Depending on the error_reporting you have set up in php.ini, you might also see an error message:
However, I didn't say this can't be overcome. To have variables within a function accessible from outside it (andvice-versa), all you need to do is first declare them "global" with the - you guessed it! - global keyword.
Here is a rewrite of the earlier example, this time declaring the $today variable global:
<?php
// define a variable in the main program
$today = "Tuesday";
// define a function
function getDay() {
// make the variable global
global $today;
// define a variable inside the function
$today = "Saturday";
// print the variable
print "It is $today inside the function<br />";
}
// print the variable
print "It is $today before running the function<br />";
// call the function
getDay();
It is Saturday inside the functionIt is Tuesday outside the function
Today is
Notice: Undefined variable: today in x1.php on line 10
// print the variable print "It is $today after running the function";
?>
And here is the output:
Thus, once a variable is declared global, it is available at the global level, and can be manipulated both insideand outside a function.PHP also comes with so-called superglobal variables - variables that are always available, regardless of whetheryou're inside a function or outside it. You've already seen some of these special variables in action: the$_SERVER, $_POST and $_GET variables are all superglobals, which is why you can access things like the
currently-executing script's name or form values even inside a function.
Superglobals are a Good Thing™, because they're always there when you need them, and you don't need tojump through any hoops to use the data stored inside them. Read more about superglobals and variable scopeat http://www.php.net/manual/en/language.variables.predefined.php andhttp://www.php.net/manual/en/language.variables.scope.php.
Checking References
Any discussion about variables in and out of functions would be incomplete without some mention of thedifference between "passing by reference" and "passing by value". So far, all the examples you've seen haveinvolved passing arguments to a function "by value" - meaning that a copy of the variable was passed to thefunction, while the original variable remained untouched. However, PHP also allows you to pass "by reference" -meaning that instead of passing a value to a function, you pass a reference to the original variable, and have thefunction act on that instead of a copy.
Confusing? Well, this is probably easier to understand with an example. Let's start with this:
<?php
// create a variable
$today = "Saturday";
// function to print the value of the variable
function setDay($day) {
$day = "Tuesday";
print "It is $day inside the function<br />";
}
// call function
setDay($today);
// print the value of the variable
print "It is $today outside the function";
?>
You've already seen this before, and you already know what the output is going to say:
This is because when the getDay() function is invoked, it passes the value "Saturday" to the function ("passing
by value"). The original variable remains untouched; only its content is sent to the function. The function thenacts on the content, modifying and displaying it.Now, look at how "passing by reference" works:
<?php
// create a variable
$today = "Saturday";
// function to print the value of the variable
function setDay(&$day) {
$day = "Tuesday";
print "It is $day inside the function<br />";
}
// call function
setDay($today);
// print the value of the variable
print "It is $today outside the function";
?>
Notice the ampersand (&) before the argument in the function definition. This tells PHP to use the variablereference instead of the variable value. When such a reference is passed to a function, the code inside thefunction acts on the reference, and modifies the content of the original variable (which the reference is pointingto) rather than a copy. If you then try retrieving the value of the original variable outside the function, it returnsthe modified value:
Now you understand why I said no discussion about variables would be complete without mentioning the twoways of passing variables. This, of course, is what the global keyword does inside a function: use a reference to
ensure that changes to the variable inside the function also reflect outside it. The PHP manual puts it best whenit says "...when you declare a variable as global $var you are in fact creating a reference to a global variable".
It is Tuesday before running the functionIt is Saturday inside the functionIt is Saturday after running the function
It is Tuesday inside the functionIt is Saturday outside the function
.It is Tuesday inside the functionIt is Tuesday outside the function
For more examples, read all about references at http://www.zend.com/manual/language.references.php.And that just about concludes this tutorial. This time you've taken a big step towards better software design bylearning how to abstract parts of your PHP code into reusable functions. You now know how to add flexibility toyour functions by allowing them to accept different arguments, and how to obtain one (or more) return valuesfrom them. Finally, you've learned a little bit about how PHP treats variables inside and outside functions.
In Part Seven, I'll be showing you how to group related functions together into classes, and also telling you allabout the cool new features in the PHP 5 object model. You definitely don't want to miss that one!
Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Monday, September 4, 2006
CORRECTION5:39AM PDT � heymcd
$x < sizeof($args) should be $x < $numArgs
Paying attention,Bill.
Wednesday, June 6, 2007
I'VE BEEN READING PHP 101 FROM THE FIRST SECTION, NON-STOP, AND STILL READINGON ...9:37AM PDT � zhijunsheng
I'm an experienced java programmer but new to PHP. None of other PHP tutorials I found fits me better thanthis one. Thanks a lot! Great job!
Friday, June 22, 2007
SUPER JOB!5:36AM PDT � rdelude
This is an excellent tutorial which has been very helpful to me. Thanks much. Best explanation of PHP functionsI have ever seen.
by Vikram Vaswani | 6 comments | Saturday, August 7, 2004
Alphabet SoupBack To ClassAnimal AnticsGoing DeeperThis And ThatUnder ConstructionHands OffExtending YourselfPart 2
Alphabet Soup
So now you know how to create your own functions in PHP, and you've spent the last few days busily inspectingyour applications and turning repeated code fragments into functions. But functions are just the tip of thesoftware abstraction iceberg. Lurking underneath is a three-letter acronym that strikes fear into the hearts ofmost newbie programmers.
OOP.
If you've been programming for a while, you've probably heard the term OOP before - it stands for ObjectOriented Programming, and refers to a technique whereby you create program "objects" and then use theseobjects to build the functionality you need into your program. PHP 5 is very big on OOP - it comes with abrand-spanking-new object model which finally brings PHP objects into conformance with standard OOPprinciples and offers OO programmers a whole bunch of new goodies to play with.
Wondering how you can get in on this? Well, wonder no more. Your prayers have been answered.
Over the course of this tutorial, I'm going to take a brief look at PHP's OO capabilities (both PHP 4 and PHP 5),together with examples and explanations to demonstrate just how powerful it really is. I'll be covering most ofthe basics - classes, objects, attributes and methods - and a couple of more advanced concepts - constructors,destructors, private methods and properties, and inheritance. And if you're new to object-oriented programming,or just apprehensive about what lies ahead, don't worry - I promise this will be a lot less painful than you think.And unlike dentists, I don't lie.
Back To Class
Before beginning, though, let's make sure that you have a clear idea of the concepts involved here.
In PHP, a class is simply a set of program statements which perform a specific task. A typical class definitioncontains both variables and functions, and serves as the template from which to spawn specific instances of thatclass.
These specific instances of a class are referred to as objects. Every object has certain characteristics, orproperties, and certain pre-defined functions, or methods. These properties and methods of the object correspond directly with the variables and functions within the class definition.
Once a class has been defined, PHP allows you to spawn as many instances of the class as you like. Each ofthese instances is a completely independent object, with its own properties and methods, and can therefore bemanipulated independently of other objects. This comes in handy in situations where you need to spawn morethan one instance of an object - for example, two simultaneous database links for two simultaneous queries, ortwo shopping carts.
Classes also help you keep your code modular - you can define a class in a separate file, and include that fileonly in the scripts where you plan to use the class - and simplify code changes, since you only need to edit asingle file to add new functionality to all your spawned objects.
Animal Antics
To understand this better, pick an animal, any animal. I pick the bear, because I like bears. Now ask yourself,can you consider this bear, within the framework of OOP, as an "object"?
Why not? After all, every bear has certain characteristics - age, weight, sex - which are equivalent to objectproperties. And every bear can perform certain activities - eat, sleep, walk, run, mate - all of which areequivalent to object methods.
Let's take it a little further. Since all bears share certain characteristics, it is possible to conceive of a templateBear(), which defines the basic characteristics and abilities of every bear on the planet. Once this Bear()
("class") is used to create a new $bear ("object"), the individual characteristics of the newly-created Bear can
be manipulated independently of other Bears that may be created from the template.
Now, if you sat down to code this class in PHP 5, it would probably look something like this:
<?php
// PHP 5
// class definition
class Bear {
// define properties
public $name;
public $weight;
public $age;
public $sex;
public $colour;
// define methods
public function eat() {
echo $this->name." is eating... ";
}
public function run() { echo $this->name." is running... "; }
public function kill() { echo $this->name." is killing prey... "; }
public function sleep() { echo $this->name." is sleeping... "; } }
?>
Given this class, it's now simple to spawn as many Bears as you like, and adjust the individual properties ofeach. Take a look:
<?php
// my first bear
$daddy = new Bear;
// give him a name
$daddy->name = "Daddy Bear";
// how old is he
$daddy->age = 8;
// what sex is he
$daddy->sex = "male";
// what colour is his coat
$daddy->colour = "black";
// how much does he weigh
$daddy->weight = 300;
// give daddy a wife
$mommy = new Bear;
$mommy->name = "Mommy Bear";
$mommy->age = 7;
$mommy->sex = "female";
$mommy->colour = "black";
$mommy->weight = 310;
// and a baby to complete the family
$baby = new Bear;
$baby->name = "Baby Bear";
$baby->age = 1;
$baby->sex = "male";
$baby->colour = "black";
$baby->weight = 180;
// a nice evening in the Bear family
// daddy kills prey and brings it home
$daddy->kill();
// mommy eats it
$mommy->eat();
// and so does baby
$baby->eat();
// mommy sleeps
$mommy->sleep();
// and so does daddy
$daddy->sleep();
// baby eats some more
$baby->eat();
?>
As the illustration above shows, once new objects are defined, their individual methods and variables can beaccessed and modified independent of each other. This comes in very handy, as the rest of this tutorial willshow.
Going Deeper
Now that you've got the concepts straight, let's take a look at the nitty-gritty of a class definition.
<?php
// PHP 5
// class definition
class Bear {
// define public properties
public $name;
public $age;
// more properties
// define public methods
public function eat() {
echo $this->name." is eating... ";
// more code }
// more methods }
?>
Every class definition begins with the keyword class, followed by a class name. You can give your class anyname that strikes your fancy, so long as it doesn't collide with a reserved PHP word. A pair of curly bracesencloses all class variables and functions, which are written as you would normally code them.
PHP 5 also introduces the concept of visibility to the object model. Visibility controls the extent to which objectproperties and methods can be manipulated by the caller, and plays an important role in defining how open orclosed your class is. Three levels of visibility exist, ranging from most visible to least visible: public, privateand protected. Within the class definition, you can mark the visibility of a property or method by preceding itwith one of the keywords - public, private, or protected .
By default, class methods and properties are public; this allows the calling script to reach inside your object
instances and manipulate them directly. If you don't like the thought of this intrusion, you can mark a particularproperty or method as private or protected, depending on how much control you want to cede over the
object's internals (more on this shortly).
Since the PHP 4 object model does not include support for visibility, the class definition above would not work inPHP 4. Instead, you would need to use the following:
<?php
// PHP 4
// class definition
class Bear {
// define properties
var $name;
var $weight;
var $age;
var $sex;
var $colour;
// define methods
function eat() {
echo $this->name." is eating... ";
}
function run() {
echo $this->name." is running... ";
}
function kill() {
echo $this->name." is killing prey... ";
}
function sleep() {
echo $this->name." is sleeping... ";
}
}
?>
From the above, it should be clear that class properties and methods in PHP 4 are always public ...and thereain't nuttin' you can do about that!
In order to create a new instance of a class, you use the new keyword to assign the newly created object to a
PHP variable.
<?php
$daddy = new Bear;
?>
In English, the above would mean "create a new object of class Bear() and assign it to the variable $daddy ".
You can now access all the methods and properties of the class via this variable. For example, the code
<?php
$daddy->name = "Daddy Bear";
?>
would mean "assign the value Daddy Bear to the variable $name of this specific instance of the class Bear()",
while the statement
<?php
$daddy->sleep();
?>
would mean "execute the function sleep() for this specific instance of the class Bear()".
Note the -> symbol used to connect objects to their properties or methods, and the fact that the $ symbol is
omitted when accessing properties of a class instance.
This And That
In case you need to access functions or variables within the class definition itself, both PHP 4 and PHP 5 offer the$this keyword, which is used to refer to "this" class. To see how this works, let's alter the eat() method to
accept a number of food units and then add that to the bear's weight.
<?php
// PHP 5
// class definition
class Bear {
// define properties
public $name;
public $weight;
// define methods
public function eat($units) {
echo $this->name." is eating ".$units." units of food... ";
$this->weight += $units;
}
}
?>
In this case, the $this prefix indicates that the variable to be modified exists within the class - or, in English,
"add the argument provided to eat() to the variable $weight within this object". The $this prefix thus provides
a convenient way to access variables and functions which are "local" to the class.
Here's an example of how it works:
<?php
// create instance
$baby = new Bear;
$baby->name = "Baby Bear";
$baby->weight = 1000;
// now create another instance
// this one has independent values for each property
$brother = new Bear;
$brother->name = "Brother Bear";
$brother->weight = 1000;
// retrieve properties
echo $baby->name." weighs ".$baby->weight." units ";
echo $brother->name." weighs ".$brother->weight." units ";
// call eat()
$baby->eat(100);
$baby->eat(50);
$brother->eat(11);
// retrieve new values
echo $baby->name." now weighs ".$baby->weight." units ";
echo $brother->name." now weighs ".$brother->weight." units ";
?>
The output of this will read:
Under Construction
It's also possible to automatically execute a function when the class is called to create a new object. This isreferred to in geek lingo as a constructor and, in order to use it, your PHP 5 class definition must contain aspecial function, __construct().
For example, if you'd like all newly born bears to be brown and weigh 100 units, you could add this to your classdefinition:
<?php
// PHP 5
// class definition
class Bear {
// define properties
public $name;
public $weight;
public $age;
public $colour;
// constructor
Baby Bear weighs 1000 unitsBrother Bear weighs 1000 unitsBaby Bear is eating 100 units of food...Baby Bear is eating 50 units of food...Brother Bear is eating 11 units of food...Baby Bear now weighs 1150 unitsBrother Bear now weighs 1011 units
public function __construct() { $this->age = 0; $this->weight = 100; $this->colour = "brown"; } // define methods }
?>
In PHP 4, your constructor must have the same name as the class. Here's the equivalent code for PHP 4:
<?php
// PHP 4
// class definition
class Bear {
// define properties
var $name;
var $weight;
var $age;
var $colour;
// constructor
function Bear() {
$this->age = 0;
$this->weight = 100;
$this->colour = "brown";
}
// define methods
}
?>
Now, try creating and using an instance of the class:
<?php
// create instance
$baby = new Bear;
$baby->name = "Baby Bear";
echo $baby->name." is ".$baby->colour." and weighs ".$baby->weight." units at birth";
?>
Here, the constructor automatically sets default properties every time an object of the class is instantiated.Therefore, when you run the script above, you will see this:
Hands Off
As noted previously, PHP 5 makes it possible to mark class properties and methods as private, which means
that they cannot be manipulated or viewed outside the class definition. This is useful to protect the innerworkings of your class from manipulation by object instances. Consider the following example, which illustratesthis by adding a new private variable, $_lastUnitsConsumed, to the Bear() class:
<?php
// PHP 5
// class definition
class Bear {
// define properties
public $name;
public $age;
public $weight;
private $_lastUnitsConsumed;
// constructor
public function __construct() {
$this->age = 0;
$this->weight = 100;
$this->_lastUnitsConsumed = 0;
}
// define methods
public function eat($units) {
echo $this->name." is eating ".$units." units of food... ";
$this->weight += $units;
$this->_lastUnitsConsumed = $units;
}
public function getLastMeal() {
echo "Units consumed in last meal were ".$this->_lastUnitsConsumed." ";
}
}
?>
Now, since the $_lastUnitsConsumed variable is declared as private, any attempt to modify it from an object
Baby Bear is brown and weighs 100 units at birth
instance will fail. Here is an example:
<?php
$bob = new Bear;
$bob->name = "Bobby Bear";
$bob->eat(100);
$bob->eat(200);
echo $bob->getLastMeal();
// the next line will generate a fatal error
$bob->_lastUnitsConsumed = 1000;
?>
In a similar way, class methods can also be marked as private - try it out for yourself and see.
Extending Yourself
Two of the best things about OOP, whether in PHP 4 or in PHP 5, are extensibility and inheritance. Very simply,this means that you can create a new class based on an existing class, add new features (read: properties andmethods) to it, and then create objects based on this new class. These objects will contain all the features of theoriginal parent class, together with the new features of the child class.
As an illustration, consider the following PolarBear() class, which extends the Bear() class with a new
method.
<?php
// PHP 5
// class definition
class Bear {
// define properties
public $name;
public $weight;
public $age;
public $sex;
public $colour;
// constructor
public function __construct() {
$this->age = 0;
$this->weight = 100;
}
// define methods
public function eat($units) {
echo $this->name." is eating ".$units." units of food... ";
$this->weight += $units;
}
public function run() {
echo $this->name." is running... ";
}
public function kill() {
echo $this->name." is killing prey... ";
}
public function sleep() {
echo $this->name." is sleeping... ";
}
}
// extended class definition
class PolarBear extends Bear {
// constructor
public function __construct() {
parent::__construct();
$this->colour = "white";
$this->weight = 600;
}
// define methods
public function swim() {
echo $this->name." is swimming... ";
}
}
?>
The extends keyword is used to extend a parent class to a child class. All the functions and variables of the
parent class immediately become available to the child class. This is clearly visible in the following code snippet:
<?php
// create instance of Bear()
$tom = new Bear;
$tom->name = "Tommy Bear";
// create instance of PolarBear() $bob = new PolarBear; $bob->name = "Bobby Bear";
// $bob can use all the methods of Bear() and PolarBear() $bob->run(); $bob->kill(); $bob->swim();
// $tom can use all the methods of Bear() but not PolarBear() $tom->run(); $tom->kill(); $tom->swim();
?>
In this case, the final call to $tom->swim() will fail and cause an error, because the Bear() class does not
contain a swim() method. However, none of the calls to $bob->run() or $bob->kill() will fail, because as a
child of the Bear() class, PolarBear() inherits all the methods and properties of its parent.
Note how the parent class constructor has been called in the PolarBear() child class constructor - it's a good
idea to do this so that all necessary initialization of the parent class is carried out when a child class isinstantiated. Child-specific initialization can then be done in the child class constructor. Only if a child class doesnot have a constructor, is the parent class constructor automatically called.
You can do this in PHP 4, too. Here's a PHP 4 version of the PolarBear class definition:
<?php
// PHP 4
// extended class definition
class PolarBear extends Bear {
// constructor
function PolarBear() {
parent::Bear();
$this->colour = "white";
$this->weight = 600;
}
// define methods
function swim() {
echo $this->name." is swimming... ";
}
}
?>
To prevent a class or its methods from being inherited, use the final keyword before the class or method name (this is new in PHP 5 and will not work in older versions of PHP). Here's an example, which renders the Bear()
class un-inheritable (if that's actually a word):
<?php
// PHP 5
// class definition
final class Bear {
// define properties
// define methods
}
// extended class definition
// this will fail because Bear() cannot be extended
class PolarBear extends Bear {
// define methods
}
// create instance of PolarBear()
// this will fail because Bear() could not be extended
$bob = new PolarBear;
$bob->name = "Bobby Bear";
echo $bob->weight;
?>
PHP 101 (part 7): The Bear Necessities - Part 2
Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Monday, September 18, 2006
VISIBILITY4:19PM PDT � pie art [unregistered]
I ran this script, which I pick from this page;
<?php // PHP 5
// class definition public class Bear {
// define public properties public $name; public $age;
// more properties
// define public methods public function eat() { echo $this->name." is eating...\n"; // more code }
// more methods }
?> <?php // PHP 5
// class definition public class Bear {
// define public properties public $name; public $age;
// more properties
// define public methods public function eat() { echo $this->name." is eating...\n"; // more code }
// more methods }
but I got an error message as below;Parse error: syntax error, unexpected T_PUBLIC in c:\wamp\www\WebDev\test\PHP OOP\visibility_public_class.php on line 5
this is a bit of my server description:Apache version : Apache/1.3.33 (Win32) PHP version : 5.0.4 MySQL version : 4.1.10a-nt - extension : mysqli
why is this happened? isn't a class can be declared as public/private in PHP5??>
Monday, October 23, 2006
PUBLIC CLASS8:55PM PDT � jana2
You don't need to declare the class itself as public, the methods and properties within can be public or privateand whatever but not the class itself. If you think about it, what would be the benefit of a non-public class? no one would be able to call it!
Private methods and properties stop developers from calling or changing these from their code, changes and calls can only be made from within the class. This can't work with the class itself because it needs to be called in order to be used!
Saturday, November 4, 2006
CLASS TUTORIAL5:01PM PST � rockinronnie [unregistered]
Thank you so much for an up to date, clearly written tutorial using simple examples that even us newbies canunderstand.
Tuesday, November 14, 2006
UN-INHERITABLE12:58PM PST � Red [unregistered]
un-inheritable is a word but you do not need a hyphen. So yeah, neat tut on classes and PHP.
*moves on to the next chapter*
Tuesday, February 13, 2007
PUBLIC CLASSES1:07PM PST � Luke [unregistered]
jana2 said, "If you think about it, what would be the benefit of a non-public class? no one would be able to callit!"
He/she was probably thinking of java: classes can be defined in other classes and only directly usable by them.For example, whatever Set implementations are given by Collections.singleton() or Collections.emptySet(), they're not public classes.
Tuesday, March 20, 2007
PUBLIC CLASS11:37AM PDT � Luxvero [unregistered]
If PHP has no public/private/protected attribute for CLASSES, why is it writen right below "Going Deeper":
<?php// PHP 5
// class definitionpublic class Bear {
Huh?
PHP 101 (part 8): Databases and Other Animals - Part 1All Skill Levels PHP101 PHP5 Tutorials
by Vikram Vaswani | 5 comments | Tuesday, August 31, 2004
Mix and MatchBuilding BlocksAnimal MagnetismHello Database!Different Strokes......for Different FolksPHP 101 (part 8): Databases and Other Animals - Part 2
Mix and Match
One of the most compelling things PHP has going for it is its support for a variety of database managementsystems, including MySQL, PostgreSQL, Oracle and Microsoft Access. By virtue of this support, PHP developerscan create sophisticated data-driven Web applications at a fraction of the time and cost required by competingalternatives. And nowhere is this more clear than in PHP's longtime support of MySQL, the very fast, veryreliable and very feature-rich open-source RDBMS.
By using PHP and MySQL together, developers can benefit from huge savings on the licensing costs ofcommercial alternatives, and also leverage off the tremendous amount of thought PHP and MySQL developershave put into making sure that the two packages work together seamlessly and smoothly. And since both PHPand MySQL are open-source projects, when you use the two of them together you know you're getting the mostup-to-date technology available. And that's always a good thought to go to bed with.
OK. Enough of the marketing talk. Let's get down to business.
In this issue of PHP 101, I'm going to show you how to use PHP to extract data from a database, and use thatdata to dynamically build a Web page. In order to try out the examples in this tutorial, you'll need a workingMySQL installation, which you can obtain from the MySQL Web site at http://www.mysql.com/. If you havesome knowledge of SQL (Structured Query Language, the language used to interact with a database server)you'll find it helpful, but it's not essential.
Building Blocks
In order to use MySQL and PHP together, your PHP build must include support for MySQL. On UNIX, this isaccomplished by adding the --with-mysql option to the configure script when building PHP on UNIX, and
pointing PHP to the MySQL client libraries. On Windows, the MySQL client libraries are built in to PHP 4 andactivated by default. In PHP 5, pre-built .dll files are included with the Windows distribution. Read more aboutthis at http://www.php.net/manual/en/ref.mysql.php.
Unix users should note that PHP 4 ships with a set of MySQL client libraries, which are activated by default;however, PHP 5 no longer bundles these libraries due to licensing issues, so you need to obtain, install andactivate them yourself. They're included with the MySQL distribution, and are installed automatically when youinstall MySQL. To activate the MySQL extension, ext/mysql, add the --with-mysql option to PHP's configure
script. For more information on this change, readhttp://www.php.net/manual/en/faq.databases.php#faq.databases.mysql.php5.
And finally (as if all that wasn't quite confusing enough) PHP 5 also comes with a new MySQL extension, called ext/mysqli (MySQL Improved). You can use this new extension to access the new features in MySQL 4.1.2 or
better, and to gain the benefits of improved speed and security. To activate this extension on UNIX, add the--with-mysqli option to PHP's configure script, and point PHP to the mysql_config program that comes with
MySQL 4.1 and above. For Windows users, a pre-built version of ext/mysqli is included in the win32 PHP
distribution. Read more about this at http://www.php.net/manual/en/ref.mysqli.php.
To figure out which extension you need, use the following rule of thumb:
If you need the new features in MySQL 4.1.2 or better, or if you're using an older version of MySQL but still wantto benefit from the speed/security improvements in the new extension, use ext/mysqli.
If you don't fall into either of the categories above, or don't know what I'm talking about, use regularext/mysql.
In case you were wondering, this tutorial covers both ext/mysql and ext/mysqli, so you actually get two for
the price of one. Keep reading, and let me introduce you to MySQL.
Animal Magnetism
Every MySQL database is composed of one or more tables. These tables, which structure data into rows andcolumns, are what lend organization to the data.
Here's an example of what a typical table looks like:
As you can see, a table divides data into rows, with a new entry (or record) on every row. The data in each row is further broken down into cells (or fields), each of which contains a value for a particular attribute of the data.For example, if you consider the record for the country "India", you'll see that the record is clearly divided intoseparate fields for record number, country name and national animal.The rows within a table are not arranged in any particular order - they can be sorted alphabetically, by number,by name, or by any other criteria you choose to specify. It is therefore necessary to have some method ofidentifying a specific record in a table. In the example above, each record is identified by a unique number; thisunique field is referred to as the primary key for that table.
You use the Structured Query Language, SQL, to interact with the MySQL server and tell it to create a table,mark a field as primary, insert records, edit records, retrieve records... basically, anything that involvesmanipulating the data or the database. To see how this works, examine the following SQL, which creates thetable above:
+----+-----------+----------+| id | country | animal |+----+-----------+----------+| 1 | America | eagle || 2 | China | dragon || 3 | England | lion || 4 | India | tiger || 5 | Australia | kangaroo || 6 | Norway | elk |+----+-----------+----------+
CREATE DATABASE testdb;
CREATE TABLE `symbols` (
`id` int(11) NOT NULL auto_increment,
`country` varchar(255) NOT NULL default '',
`animal` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`)
) TYPE=MyISAM;
INSERT INTO `symbols` VALUES (1, 'America', 'eagle');
INSERT INTO `symbols` VALUES (2, 'China', 'dragon');
INSERT INTO `symbols` VALUES (3, 'England', 'lion');
INSERT INTO `symbols` VALUES (4, 'India', 'tiger');
INSERT INTO `symbols` VALUES (5, 'Australia', 'kangaroo');
INSERT INTO `symbols` VALUES (6, 'Norway', 'elk');
You can enter these commands either interactively or non-interactively through the MySQL commandline clientprogram, which you run by navigating to the mysql/bin directory from your shell or DOS box and typing - with
no ; because this is a shell command - either mysql, or mysql db_name if you want to choose an existing
database to work with. Read http://dev.mysql.com/doc/mysql/en/mysql.html for more information on how touse the MySQL commandline client, and the tutorial athttp://www.melonfire.com/community/columns/trog/article.php?id=39 to understand what each of the SQLcommands above does. SQL is a lot like spoken English, so it won't take you very long to pick it up. Just don'ttry to turn those backticks into single quotation marks.
Once the data has been imported, run a quick SELECT query to check that everything is working as it should be:
In English, the query above means "show me all the records from the table named symbols". If you saw the
same output as above, you're good to go!
Hello Database!
Now, let's use PHP to do exactly the same thing. You could use PHP to set up the database from the start, but asours already exists we'll simply fire a SELECT query at the database 'testdb', and display the results in an HTML
page:
<html>
<head>
<basefont face="Arial">
</head>
<body>
<?php
// set database server access variables:
$host = "localhost";
$user = "test";
$pass = "test";
$db = "testdb";
// open connection
$connection = mysql_connect($host, $user, $pass) or die ("Unable to connect!");
// select database
mysql_select_db($db) or die ("Unable to select database!");
// create query
$query = "SELECT * FROM symbols";
// execute query
$result = mysql_query($query) or die ("Error in query: $query. ".mysql_error());
// see if any rows were returned
if (mysql_num_rows($result) > 0) {
// yes
// print them one after another
echo "<table cellpadding=10 border=1>";
while($row = mysql_fetch_row($result)) {
echo "<tr>";
echo "<td>".$row[0]."</td>";
echo "<td>" . $row[1]."</td>";
echo "<td>".$row[2]."</td>";
echo "</tr>";
}
echo "</table>";
}
else {
// no
// print status message
echo "No rows found!";
}
mysql> SELECT * FROM `symbols`;+----+-----------+----------+| id | country | animal |+----+-----------+----------+| 1 | America | eagle || 2 | China | dragon || 3 | England | lion || 4 | India | tiger || 5 | Australia | kangaroo || 6 | Norway | elk |+----+-----------+----------+6 rows in set (0.06 sec)
// free result set memory mysql_free_result($result);
// close connection mysql_close($connection);
?>
</body> </html>
Here's what the result looks like:
As you can see, using PHP to get data from a database involves several steps, each of which is actually apre-defined PHP function. Let's dissect each step:
The first thing to do is specify some important information needed to establish a connection to thedatabase server. This information includes the server name, the username and password required to gainaccess to it, and the name of the database to query. These values are all set up in regular PHP variables.<?php
$host = "localhost";
$user = "test";
$pass = "test";
$db = "testdb";
?>
1.
To begin communication with a MySQL database server, you need to open a connection to that server. Allcommunication between PHP and the database server takes place through this connection.In order to initialize this connection, PHP offers the mysql_connect() function:
All the parameters in mysql_connect()are optional, but there are three you will generally need to use
anywhere beyond your own machine: the database server name, username and password. If thedatabase server and the Web server are running on the same physical machine, you can use localhost
as the database server name this is in fact the default value supplied by PHP.
mysql_connect() returns a "link identifier", which is stored in the variable $connection. This identifier is
used when communicating with the database.
2.
Once you have a connection to the database, you must select a database for use with themysql_select_db() function:
<?php
mysql_select_db($db) or die ("Unable to select database!");
?>
This function must be passed the name of the database to be used for all subsequent queries. An optionalsecond argument here is the link identifier; if no identifier is specified, the last opened link is assumed. Ifyou have two or more database connections open simultaneously, it's a good idea to specify the linkidentifier as the second argument to mysql_select_db() - and indeed to all other mysql_* functions in
the script, so that PHP doesn't get confused about which connection to use where.
3.
The next step is to create the query and execute it. This is accomplished with the mysql_query()
function.<?php
$query = "SELECT * FROM symbols";
$result = mysql_query($query) or die ("Error in query: $query. ".mysql_error());
?>
This function also needs two parameters: the query string and the link identifier for the connection. Again,if no link identifier is specified, the last opened link is used. Depending on whether or not the query wassuccessful, the function returns true or false; a failure can be caught via the ...or die() clause of the
statement, and the mysql_error() function can be used to display the corresponding error message.
4.
If mysql_query() is successful, the result set returned by the query is stored in the variable $result.
This result set may contain one or more rows or columns of data, depending on your query. You canretrieve specific subsets of the result set with different PHP functions, including the one used here - themysql_fetch_row() function - which fetches a single row of data as an array called $row. Fields in that
row can then be accessed using standard PHP array notation.Each time you call mysql_fetch_row(), the next record in the result set is returned. This makes
mysql_fetch_row() very suitable for use in a while() or for() loop.
<?php
if (mysql_num_rows($result) > 0) {
while($row = mysql_fetch_row($result)) {
echo "<td>".$row[0]."</td>";
echo "<td>".$row[1]."</td>";
echo "<td>".$row[2]."</td>";
}
}
?>
Notice that the call to mysql_fetch_row() is wrapped in a conditional test, which first checks to see if any
rows were returned at all. This information is provided by the mysql_num_rows() function, which contains
the number of rows returned by the query. Obviously, you can only use this function with queries thatreturn data, like SELECT or SHOW.It is not appropriate for use with INSERT, UPDATE, DELETE or similar
queries.
There are several other alternatives to mysql_fetch_row(), which will be explained a little later.
5.
Finally, since each result set returned after a query occupies memory, it's a good idea to use themysql_free_result() function to free up the used memory. After the result set is freed, if no further
queries are to be run, you can close the connection to the MySQL server with mysql_close().
<?php
mysql_free_result($result);
mysql_close($connection);
?>
6.
Different Strokes...
You can also use PHP's mysql_fetch_row() and list() functions to obtain a simple array of values, and then
assign these values to different variables - a variation of the technique in the previous section. Take a look (onlythe while() loop changes):
<html>
<head>
<basefont face="Arial">
</head>
<body>
<?php
// set server access variables
$host = "localhost";
$user = "test";
$pass = "test";
$db = "testdb";
// open connection
$connection = mysql_connect($host, $user, $pass) or die ("Unable to connect!");
// select database
mysql_select_db($db) or die ("Unable to select database!");
// create query
$query = "SELECT * FROM symbols";
// execute query
$result = mysql_query($query) or die ("Error in query: $query. ".mysql_error());
// free result set memory mysql_free_result($result);
// close connection mysql_close($connection);
?>
</body> </html>
In this case, the list() function is used to assign different elements of the result set to PHP variables, which
are then used when rendering the page.
You can use PHP's mysql_fetch_assoc() function to represent each row as an associative array of field-value
pairs - a minor variation of the technique used above:
<html>
<head>
<basefont face="Arial">
</head>
<body>
<?php
// set server access variables
$host = "localhost";
$user = "test";
$pass = "test";
$db = "testdb";
// open connection
$connection = mysql_connect($host, $user, $pass) or die ("Unable to connect!");
// select database
mysql_select_db($db) or die ("Unable to select database!");
// create query
$query = "SELECT * FROM symbols";
// execute query
$result = mysql_query($query) or die ("Error in query: $query. ".mysql_error());
// see if any rows were returned
if (mysql_num_rows($result) > 0) {
// yes
// print them one after another
echo "<table cellpadding=10 border=1>";
while($row = mysql_fetch_assoc($result)) {
echo "<tr>";
echo "<td>".$row['id']."</td>";
echo "<td>".$row['country']."</td>";
echo "<td>".$row['animal']."</td>";
echo "</tr>";
}
echo "</table>";
}
else {
// no
// print status message
echo "No rows found!";
}
// free result set memory
mysql_free_result($result);
// close connection
mysql_close($connection);
?>
</body>
</html>
Notice that in this case, field values are accessed using the field name instead of the index.
Of all the alternatives, however, the function I like the most is the mysql_fetch_object() function, which
returns each row as an object (remember them from Part Seven?) with properties corresponding to the fieldnames:
<html>
<head>
<basefont face="Arial">
</head>
<body>
<?php
// set server access variables
$host = "localhost";
$user = "test"; $pass = "test"; $db = "testdb";
// open connection $connection = mysql_connect($host, $user, $pass) or die ("Unable to connect!");
// select database mysql_select_db($db) or die ("Unable to select database!");
// create query $query = "SELECT * FROM symbols";
// execute query $result = mysql_query($query) or die ("Error in query: $query. ".mysql_error());
// see if any rows were returned if (mysql_num_rows($result) > 0) { // yes // print them one after another echo "<table cellpadding=10 border=1>"; while($row = mysql_fetch_object($result)) { echo "<tr>"; echo "<td>".$row->id."</td>"; echo "<td>".$row->country."</td>"; echo "<td>".$row->animal."</td>"; echo "</tr>"; } echo "</table>"; } else { // no // print status message echo "No rows found!"; }
// free result set memory mysql_free_result($result);
// close connection mysql_close($connection);
?>
</body> </html>
Here, each $row object is created with properties corresponding to the field names in that row. Row values can
thus be accessed using standard object->property notation.
If you're the type that likes to have your cake and eat it too, you will probably enjoy the mysql_fetch_array()
function, which returns both an associative array and a numerically-indexed array, a combination of themysql_fetch_row() and mysql_fetch_assoc() functions. Read about it at
If you're using PHP 5, you can do the same thing using the new ext/mysqli extension, which offers a number of
new features. This extension can be used in two ways: procedural (using functions), and object-oriented (usingclass methods and properties). Consider the next script, which uses ext/mysqli in a procedural manner:
<html>
<head>
<basefont face="Arial">
</head>
<body>
<?php
// set server access variables
$host = "localhost";
$user = "test";
$pass = "test";
$db = "testdb";
// open connection
$connection = mysqli_connect($host, $user, $pass, $db) or die ("Unable to connect!");
// create query
$query = "SELECT * FROM symbols";
// execute query
$result = mysqli_query($connection, $query) or die ("Error in query: $query. ".mysqli_error());
// see if any rows were returned
if (mysqli_num_rows($result) > 0) {
// yes
// print them one after another
echo "<table cellpadding=10 border=1>";
while($row = mysqli_fetch_row($result)) {
echo "<tr>";
echo "<td>".$row[0]."</td>";
echo "<td>".$row[1]."</td>";
echo "<td>".$row[2]."</td>";
echo "</tr>";
} echo "</table>"; } else { // no // print status message echo "No rows found!"; }
// free result set memory mysqli_free_result($result);
// close connection mysqli_close($connection);
?>
</body> </html>
As you can see, this looks a lot like the code written for ext/mysql. The only real difference - at least to the
naked eye - is the fact that function names now begin with mysqli_* instead of mysql_*. Of course, there are awhole bunch of differences under the hood: ext/mysqli is faster, more secure and more powerful than regular
ext/mysql, and also includes support for prepared statements, bound result sets, multiple simultaneous queries,
transactions and a whole bunch of other cool stuff.
You can also use ext/mysqli in an object-oriented way, where each task - connecting, querying, fetching - is
actually a method of the mysqli() object:
<html>
<head>
<basefont face="Arial">
</head>
<body>
<?php
// set server access variables
$host = "localhost";
$user = "test";
$pass = "test";
$db = "testdb";
// create mysqli object
// open connection
$mysqli = new mysqli($host, $user, $pass, $db);
// check for connection errors
if (mysqli_connect_errno()) {
die("Unable to connect!");
}
// create query
$query = "SELECT * FROM symbols";
// execute query
if ($result = $mysqli->query($query)) {
// see if any rows were returned
if ($result->num_rows > 0) {
// yes
// print them one after another
echo "<table cellpadding=10 border=1>";
while($row = $result->fetch_array()) {
echo "<tr>";
echo "<td>".$row[0]."</td>";
echo "<td>".$row[1]."</td>";
echo "<td>".$row[2]."</td>";
echo "</tr>";
}
echo "</table>";
}
else {
// no
// print status message
echo "No rows found!";
}
// free result set memory
$result->close();
}
else {
// print error message
echo "Error in query: $query. ".$mysqli->error;
}
// close connection
$mysqli->close();
?>
</body>
</html>
Here, the new keyword is used to instantiate an object of class mysqli, and pass the object constructor
connection information (including the database name). The resulting object, stored in the variable $mysqli, then
exposes methods and properties to perform the tasks of querying, fetching and processing rows, and handlingerrors.
If you look closely at the two scripts above, you'll notice the numerous similarities between the function andmethod names, and the structure of the script. Of the two, though, the object-oriented method isrecommended, especially in light of the new object model in PHP 5.
A couple of other important differences to keep in mind:
With ext/mysqli, you can include the database name in the arguments passed to the mysqli_connect()
function or to the mysqli()constructor.
When calling mysqli_query() or the mysqli object's query() method, the link identifier is mandatory, not
optional.PHP 101 (part 8): Databases and Other Animals - Part 2
Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Thursday, May 17, 2007
SMALL CORRECTION7:03AM PDT � stefantalpalaru [unregistered]
Please remove "or the mysqli object's query() method, " from the last statement as it doesn't make sense. The"mysqli" object is already attached to a connection.
Tuesday, June 5, 2007
HELLO DATABASE5:01AM PDT � Stanley [unregistered]
I am an elementary stage beginner. Someone installed Mysql and PHP for me. Sure, I find the tutorial veryhelpful. But now I have a problem. I tried to run the script under 'Hello Database' but only received on my browser window this message :Fatal error: Call to undefined function mysql_connect() in c:Inetpubwwwrootdatabase.php on line 19.What am I doing wrongly?
HELLO DATABASE5:11AM PDT � Stanley [unregistered]
I am an elementary stage beginner. Someone installed Mysql and PHP for me. Sure, I find the tutorial veryhelpful. But now I have a problem. I tried to run the script under 'Hello Database' but only received on my browser window this message :Fatal error: Call to undefined function mysql_connect() in c:Inetpubwwwrootdatabase.php on line 19.What am I doing wrongly?
Wednesday, June 6, 2007
THANKS AGAIN!1:36PM PDT � codinghorse
I just want to stop to say "Thanks for the great tut!" before continuing with part 8.
Friday, June 8, 2007
COMANT LINE SYNTAX7:55PM PDT � rbstimers
On my machine i had to use a different syntax for the command line. i removed all the ''''''s from the outsidethe ()'s, in other words
CREATE TABLE `symbols` (`id` int(11) NOT NULL auto_increment,
became
CREATE TABLE symbols (id int(11) NOT NULL auto_increment,
and
INSERT INTO `symbols` VALUES (1, 'America', 'eagle');
became
INSERT INTO symbols VALUES (1, 'America', 'eagle');
with this change it worked fine. Hope this helps someone. Love the tutorial.
PHP 101 (part 9): SQLite My Fire! - Part 1All Skill Levels PHP101 PHP5 Tutorials
by Vikram Vaswani | 1 comment | Thursday, September 16, 2004
Hard ChoicesMaking New FriendsThe Bookworm TurnsAnatomy ClassDifferent StrokesAdding to the CollectionPHP 101 (part 9): SQLite My Fire! - Part 2
Hard Choices
If you've been paying attention, you now know how to use PHP's MySQL API to perform queries and processresult sets. You might even have started thinking about how to re-program your site to run off a MySQLdatabase. All of this is a Good Thing - it means you're getting comfortable with using PHP's database support topower your applications - but there's still a little further to go.
As you saw in Part Eight, enabling MySQL support in PHP 5.0 is not as simple as it used to be. Instead ofsupporting MySQL out of the box, PHP now requires you to make all kinds of decisions about versions andlibraries before allowing you to hook your scripts up to a MySQL database. If you're lazy (and deep down, weboth know you are), you might instead prefer to try a simpler option: the SQLite database engine.
Built-in SQLite support is new to PHP 5.0, and offers users a lightweight database system that is fast, efficientand gets the job done. Since it's enabled by default in PHP 5.0, it provides a viable alternative to MySQL; youcan use it out of the box, without spending time on version checks and library downloads; just install PHP 5 andstart typing. That's why I'm devoting a whole tutorial to it - so get out of bed, make yourself some coffee andlet's get started!
Making New Friends
Before getting into the code, let's make sure that you have a clear idea of what SQLite is (and isn't). UnlikeMySQL, which operates on a client-server paradigm, SQLite is a file-based database engine and uses file I/O(input/output) functions to store and read databases from files on disk. It's also much, much smaller thanMySQL - the command-line version of SQLite weighs in at under 200 KB - and supports most of the SQLcommands you're used to.
This small size shouldn't deceive you, however - according to the official SQLite Web site, SQLite supportsdatabases up to 2 terabytes in size and is actually faster than MySQL in certain situations. SQLite database filesare easily portable, and SQLite databases created on Windows work fine on *NIX platforms and vice-versa.
One of SQLite's more interesting aspects is that it is completely typeless. Fields in an SQLite database need notbe associated with a specific type, and even if they are, you can still insert values of different types into them(there is one exception to this rule, but I'll get to that later). This is important, because it means that if you'reconcerned about values of the wrong type getting into your tables, you need to write code to implement typechecking in your application.
Another important difference between MySQL and SQLite lies in their licensing policies: unlike MySQL, SQLitesource code is completely public-domain, which means that you can use and distribute it however you choose inboth commercial and non-commercial products. Take a look at http://sqlite.org/copyright.html for more on this.
In order to use SQLite and PHP together, your PHP build must include SQLite. This is enabled by default in boththe UNIX and Windows versions of PHP 5. Read more about this athttp://www.php.net/manual/en/ref.sqlite.php. If you're a PHP 4.x user, though, don't lose heart - you can stilluse SQLite, by manually downloading and installing php_sqlite.dll from http://snaps.php.net (Windows) or thelatest tarball from http://pecl.php.net/package/SQLite (UNIX). You don't need to download anything else; theSQLite 'client' is its own engine.
The Bookworm Turns
As with MySQL, you use regular SQL commands to interact with an SQLite database. The exact SQL syntax usedby SQLite is listed at http://sqlite.org/lang.html, but for most operations SQL commands are standard.
Here's an example, which sets up the table I'll be using in this tutorial:
C:\WINDOWS\Desktop\sqlite>sqlite library.db
SQLite version 2.8.15
Enter ".help" for instructions
sqlite> create table books (
...> id integer primary key,
...> title varchar(255) not null,
...> author varchar(255) not null
...>);
sqlite> insert into books (title, author) values ('The Lord Of The Rings', 'J.R.R. Tolkien');
sqlite> insert into books (title, author) values ('The Murders In The Rue Morgue', 'Edgar Allen
Poe');
sqlite> insert into books (title, author) values ('Three Men In A Boat', 'Jerome K. Jerome');
sqlite> insert into books (title, author) values ('A Study In Scarlet', 'Arthur Conan Doyle');
sqlite> insert into books (title, author) values ('Alice In Wonderland', 'Lewis Carroll');
sqlite> .exit
You can enter these commands either interactively or non-interactively through the SQLite commandlineprogram, which is available at http://sqlite.org/download.html as a precompiled binary for Windows and Linux.SQLite 2.* is the version currently used in both branches of PHP, with SQLite 3.* support anticipated for PDOand later PHP 5.* releases.
Extract the downloaded files to a directory of your choice, cd into it from your shell or DOS box and type 'sqlite'.You should see the SQLite version information and the line:
Read http://sqlite.org/sqlite.html for more information on how to use the commandline program.Once the data has been imported into the database file library.db, run a quick SELECT query to check if
everything is working as it should:
Enter ".help" for instructions
sqlite> select * from books;
If you saw the same output as above, you're good to go!
Anatomy Class
Now, use PHP to communicate with SQLite, generate the same result set and format it as an HTML page. Here'sthe code:
<html>
<head></head>
<body>
<?php
// set path of database file
$db = $_SERVER['DOCUMENT_ROOT']."/../library.db";
// open database file
$handle = sqlite_open($db) or die("Could not open database");
// generate query string
$query = "SELECT * FROM books";
// execute query
$result = sqlite_query($handle, $query) or die("Error in query:
If all goes well, you should see something like this:
If you remember what you learned in Part Eight, the PHP script above should be easy to decipher. In case youdon't, here's a fast rundown:
The ball starts rolling with the sqlite_open() function, which accepts the name of the database file as
argument and attempts to open it. If this database file cannot be found, an empty database file will becreated with the supplied name (assuming the script has write access to the directory).<?php
$db = $_SERVER['DOCUMENT_ROOT']."/../library.db";
$handle = sqlite_open($db) or die("Could not open database");
?>
The database file library.db needs to be kept somewhere it can't be accessed through the browser by
visitors to your site. That means that you need to create it outside your public_html, www or htdocsdirectory, in a directory that allows your scripts read/write permissions. Web hosting companies generallywill offer a space above your web-visible directory where you can do this.$_SERVER['DOCUMENT_ROOT']."/.." is the directory directly above your web-visible directory.
If successful, the sqlite_open() function returns a handle to the file, which is stored in the variable
$handle and is used for all subsequent communication with the database.
1.
1|The Lord Of The Rings|J.R.R. Tolkien2|The Murders In The Rue Morgue|Edgar Allen Poe3|Three Men In A Boat|Jerome K. Jerome4|A Study In Scarlet|Arthur Conan Doyle5|Alice In Wonderland|Lewis Carroll
The next step is to create and execute the query, with the sqlite_query() function.
<?php
$query = "SELECT * FROM books";
$result = sqlite_query($handle, $query) or die("Error in query:
This function also needs two parameters: the database handle and the query string. Depending onwhether or not the query was successful, the function returns true or false; in the event of a failure, thesqlite_error_string() and sqlite_last_error() functions can be used to display the error that took
place.
2.
If sqlite_query() is successful, the result set returned by the query is stored in the variable $result.
You can retrieve the records in the result set with the sqlite_fetch_array() function, which fetches a
single row of data as an array called $row. Fields in that record are represented as array elements, and
can be accessed using standard index notation.Each time you call sqlite_fetch_array(), the next record in the result set is returned. This makes
sqlite_fetch_array() very suitable for use in a while() loop, in much the same way as
mysql_fetch_row() was used earlier.
<?php
if (sqlite_num_rows($result) > 0) {
echo "<table cellpadding=10 border=1>";
while($row = sqlite_fetch_array($result)) {
echo "<tr>";
echo "<td>".$row[0]."</td>";
echo "<td>".$row[1]."</td>";
echo "<td>".$row[2]."</td>";
echo "</tr>";
}
echo "</table>";
}
?>
The number of records returned by the query can be retrieved with the sqlite_num_rows() function. Or,
if what you're really interested in is the number of fields in the result set, use the sqlite_num_fields()
function instead. Of course, these are only applicable with queries that actually return records; it doesn'treally make sense to use them with INSERT, UPDATE or DELETE queries.
3.
Once you're done, it's a good idea to close the database handle and return the used memory to thesystem, with a call to sqlite_close():
<?php
sqlite_close($handle);
?>
4.
In PHP 5 you can also use the SQLite API in an object-oriented way, wherein each of the functions abovebecomes a method of the SQLiteDatabase() object. Take a look at this next listing, which is equivalent to the
$db = new SQLiteDatabase($file) or die("Could not open database");
// generate query string
$query = "SELECT * FROM books";
// execute query
// return result object
$result = $db->query($query) or die("Error in query");
// if rows exist
if ($result->numRows() > 0) {
// get each row as an array
// print values
echo "<table cellpadding=10 border=1>";
while($row = $result->fetch()) {
echo "<tr>";
echo "<td>".$row[0]."</td>";
echo "<td>".$row[1]."</td>";
echo "<td>".$row[2]."</td>";
echo "</tr>";
}
echo "</table>";
}
// all done
// destroy database object
unset($db); ?> </body> </html>
Here, the new keyword is used to instantiate an object of the class SQLiteDatabase() by passing the object
constructor the name of the database file. If the database file does not already exist, a new database file iscreated. The resulting object, stored in $db, then exposes methods and properties to perform queries. Every
query returns an instance of the class SQLiteResult(), which in turn exposes methods for fetching and
processing records.
If you look closely at the two scripts above, you'll see the numerous similarities between the procedural functionnames and the object method names. While the correspondence between the two is not perfect, it's usuallyclose enough to make it possible to guess the one if you know the other.
Different Strokes
As with the MySQL API, PHP's SQLite API offers you more than one way to skin a cat. For example, you canretrieve each row as an object with the sqlite_fetch_object() method, and access field values by using the
field names as object properties. Here's an example:
<html>
<head></head>
<body>
<?php
// set path of database file
$db = $_SERVER['DOCUMENT_ROOT']."/../library.db";
// open database file
$handle = sqlite_open($db) or die("Could not open database");
// generate query string
$query = "SELECT * FROM books";
// execute query
$result = sqlite_query($handle, $query) or die("Error in query:
Another option is to retrieve the complete result set in one fell swoop with the sqlite_fetch_all() function.
This function retrieves the complete set of records as an array of arrays; each element of the outer arrayrepresents a record, and is itself structured as an array whose elements represent fields in that record.
Here's an example, which might make this clearer:
<html>
<head></head>
<body>
<?php
// set path of database file
$db = $_SERVER['DOCUMENT_ROOT']."/../library.db";
// open database file
$handle = sqlite_open($db) or die("Could not open database");
// generate query string
$query = "SELECT * FROM books";
// execute query
$result = sqlite_query($handle, $query) or die("Error in query:
// get the complete result set as a series of nested arrays
$data = sqlite_fetch_all($result);
// all done
// close database file
sqlite_close($handle);
// check the array to see if it contains at least one record if (sizeof($data) > 0) { echo "<table cellpadding=10 border=1>"; // iterate over outer array (rows) // print values for each element of inner array (columns) foreach ($data as $row) { echo "<tr>"; echo "<td>".$row[0]."</td>"; echo "<td>".$row[1]."</td>"; echo "<td>".$row[2]."</td>"; echo "</tr>"; } echo "</table>"; } ?> </body> </html>
In all the previous examples, the database remained open while the result set was processed, because recordswere retrieved one after another with the sqlite_fetch_array() or sqlite_fetch_object() functions. The
example above is unique in that the database can be closed before the result set array is processed. This isbecause the entire result set is retrieved at once and stored in the $data array, so there really isn't any need to
leave the database open while processing it.
If your result set contains only a single field, use the sqlite_fetch_single()function, which retrieves the value
of the first field of a row. The PHP manual puts it best when it says "this is the most optimal way to retrieve datawhen you are only interested in the values from a single column of data." Take a look:
<html>
<head></head>
<body>
<?php
// set path of database file
$db = $_SERVER['DOCUMENT_ROOT']."/../library.db";
// open database file
$handle = sqlite_open($db) or die("Could not open database");
// generate query string
// this query returns only a single record with a single field
$query = "SELECT author FROM books WHERE title = 'A Study In Scarlet'";
// execute query
$result = sqlite_query($handle, $query) or die("Error in query:
// all done // close database file sqlite_close($handle); ?> </body> </html>
You can, of course, do the same thing using object notation in PHP 5. However, you need to know thatsqlite_has_more() is one function that really doesn't translate to its object method name; in an OO script, you
would need to call $result->valid();.
This script is the OO equivalent of the one above:
$db = new SQLiteDatabase($file) or die("Could not open database");
// generate query string
$query = "SELECT DISTINCT author FROM books";
// execute query
$result = $db->query($query) or die("Error in query");
// if rows exist
if ($result->numRows() > 0) {
echo "<table cellpadding=10 border=1>";
// check for more rows
while ($result->valid()) {
// get first field from each row
// print values
$row = $result->fetchSingle();
echo "<tr>";
echo "<td>".$row."</td>";
echo "</tr>";
}
echo "</table>";
}
// all done
// destroy database object
unset($db);
?>
</body>
</html>
PHP 101 (part 9): SQLite My Fire! - Part 2
Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Friday, February 16, 2007
PHP 44:34AM PST � zarezadeh
Is there a way to call sqlite functions in PHP 4?
PHP 101 (part 10): A Session In The Cookie JarAll Skill Levels PHP101 PHP5 Tutorials
by Vikram Vaswani | 3 comments | Sunday, October 3, 2004
Patience PaysParty TimeThe First SessionRemember MeRules Of The GameMeeting Old FriendsForm And FunctionAccess Granted
Patience Pays
Now that you've used PHP with MySQL and SQLite, you probably think you know everything you need to getstarted with PHP programming. In fact, you might even be thinking of cutting down your visits to Zend.comaltogether, giving up this series for something flashier and cooler...
Uh-uh. Big mistake.
You see, while built-in database support makes programming with PHP easy, it isn't the only thing that makesPHP so popular. An easy-to-use XML API and new exception handling mechanism (in PHP 5), support forpluggable modules, and built-in session management are just some of the many other features that make PHProck. And all these capabilities are going to be explored, in depth, right here in this very series, if you can justfind it in yourself to hang around a little longer. So close your eyes, take a deep breath, and read on to find outall about this tutorial's topic: sessions and cookies.
Party Time
Maybe you heard this at the last party you went to: "HTTP is a stateless protocol, and the Internet is a statelessdevelopment environment".
No? Hmmm. Obviously, you don't go to the right parties.
In simple language, all this means is that HTTP, the HyperText Transfer Protocol that is the backbone of theWeb, is unable to retain a memory of the identity of each client that connects to a Web site, and therefore treatseach request for a Web page as a unique and independent connection, with no relationship whatsoever to theconnections that preceded it. This "stateless environment" works great so long as you're aimlessly surfing theWeb, but it can cause a serious headache for sites that actually depend on the data accumulated in previousrequests. The most common example is that of an online shopping cart - in a stateless environment, it becomesdifficult to keep track of all the items you've shortlisted for purchase as you jump from one catalog page toanother.
Obviously, then, what is required is a method that makes it possible to "maintain state", allowing clientconnections to be tracked and connection-specific data to be maintained. And thus came about cookies, which allow Web sites to store client-specific information on the client system, and access the information wheneverrequired. A cookie is simply a file, containing a series of variable-value pairs and linked to a domain. When aclient requests a particular domain, the values in the cookie file are read and imported into the serverenvironment, where a developer can read, modify and use them for different purposes. A cookie is a convenientway to carry forward data from one client visit to the next.
Another common approach is to use a session to store connection-specific data; this session data is preservedon the server for the duration of the visit, and is destroyed on its conclusion. Sessions work by associating everysession with a session ID (a unique identifier for the session) that is automatically generated by PHP. Thissession ID is stored in two places: on the client using a temporary cookie, and on the server in a flat file or adatabase. By using the session ID to put a name to every request received, a developer can identify which clientinitiated which request, and track and maintain client-specific information in session variables (variable-valuepairs which remain alive for the duration of the session and which can store textual or numeric information).
Sessions and cookies thus provide an elegant way to bypass the stateless nature of the HTTP protocol, and areused on many of today's largest sites to track and maintain information for personal and commercialtransactions. Typically, you use a session to store values that are required over the course of a single visit, anda cookie to store more persistent data that is used over multiple visits.
PHP has included support for cookies since PHP 3.0, and built-in session management since PHP 4.0. Both thesefeatures are enabled by default, so you don't have to do anything special to activate them. Instead, scroll downand take a look at your first session.
The First Session
One of the standard examples used to demonstrate how a session works is the hit counter application. This is asimple counter that initializes a variable the first time you visit a Web page, and increments it each time youreload the page. The counter variable is stored in a session, which means that if you browse to another site andthen return, the last saved value of the counter will be restored (so long as you didn't destroy the session byshutting down the browser in the interim).
Take a look at the code:
<?php
// initialize a session
session_start();
// increment a session counter
$_SESSION['counter']++;
// print value
echo "You have viewed this page " . $_SESSION['counter'] . " times";
?>
To see how this works, request the script above through your browser a few times. You will notice that thecounter increases by 1 on each subsequent page load. If you open up two browser windows and request the
same page in each one, PHP will maintain and increment individual session counters for each browser instance.The session ID is used to identify which client made which request, and recreate the prior saved environment foreach individual session. This also means that if you visit one (or more) other Web sites during the same sessionand then return to the script above without shutting down your browser in the interim, your previous session willbe retrieved and recreated for you.
Every session in PHP begins with a call to the session_start() function. This function checks to see whether a
session already exists, and either restores it (if it does) or creates a new one (if it doesn't). Session variablescan then be registered by adding keys and values to the special $_SESSION superglobal array, and can be
accessed at any time during the session using standard array notation. In the example above, a key namedcounter has been added to the $_SESSION array. The first time a session is created, this key will have the value
0. On every subsequent request for the page during the same session, the previous value of the counter will beretrieved and incremented by 1.
If the example above doesn't work as advertised, check to make sure that the session.save_path variable in
your php.ini file points to a valid temporary directory for your system. This value is hard-wired to /tmp bydefault, so if you're trying the example on a Windows system, you will need to edit it to C:\Windows\temp (or your system's temporary directory).
Remember Me
Here's another example, this one asking you to log in and then storing your login name and session start time astwo session variables. This information is then used to display the total number of minutes the session has beenactive.
<?php
// initialize a session
session_start();
?>
<html>
<head></head>
<body>
<?php
if (!isset($_SESSION['name']) && !isset($_POST['name'])) {
In this example, the presence or absence of a session variable is used to decide which of the three possiblescreens to display. The session start time is also recorded in $_SESSION['start'] with the time() function,
which returns the total number of seconds between January 1 1970 and the current time. At a later stage, thevalue stored in $_SESSION['start'] is compared with the most current value of time() to calculate and display
an (approximate) display of elapsed time.
It's important to note that the call to session_start() must appear first, before any output is generated by the
script (assuming you're not using PHP's output buffering feature, which you can read about athttp://www.php.net/manual/en/ref.outcontrol.php). This is because the PHP session handler internally usesin-memory cookies to store session data, and the cookie creation headers must be transmitted to the clientbrowser before any output. If you ever see an error like this in one of your session-enabled pages:
it's usually because somewhere, somehow, some output has found its way to the browser beforesession_start() was called. Even a carriage return or a blank space outside the PHP tags surrounding
session_start() can cause this error, so watch out for them.
As noted previously, every session has a unique session ID, which PHP uses to keep track of different clients.This session ID is a long alphanumeric string, which is automatically passed by PHP from page to page so thatthe continuity of the session is maintained. To see what it looks like, use the session_id() function, as in this
simple example:
Warning: Cannot send session cache limiter - headers already sent (output started at ...)
<?php
// initialize a session
session_start();
// print session ID
echo "I'm tracking you with session ID " . session_id();
?>
When the user shuts down the client browser and destroys the session, the $_SESSION array will be flushed of all
session variables. You can also explicitly destroy a session - for example, when a user logs out - by calling thesession_destroy() function, as in the following example:
<?php
// initialize a session
session_start();
// then destroy it
session_destroy();
?>
In case you were wondering if you read that right - yes, before you can call session_destroy() to destroy a
session, you must first call session_start() to recreate it.
Remember that $_SESSION is a superglobal, so you can use it inside and outside functions without needing to
declare it as global first. The following simple example illustrates this:
<?php
// initialize a session
session_start();
// this function checks the value of a session variable
// and returns true or false
function isAdmin() {
if ($_SESSION['name'] == 'admin') {
return true;
}
else {
return false;
}
}
// set a value for $_SESSION['name']
$_SESSION['name'] = "guessme";
// call a function which uses a session variable
// returns false here
echo isAdmin()."<br />";
// set a new value for $_SESSION['name']
$_SESSION['name'] = "admin";
// call a function which uses a session variable
// returns true here
echo isAdmin()."<br />";
?>
You can read more about sessions and session handling functions athttp://www.php.net/manual/en/ref.session.php.
Rules Of The Game
A session works by using an in-memory cookie, which explains why it's only active while the browser instancethat created it is active; once the browser instance is terminated, the memory allocated to that instance isflushed and returned to the system, destroying the session cookie in the process. If you want longer-lastingcookies, you can use PHP's built-in cookie functions to write data to the user's disk as a cookie file, and read thisdata back as and when needed.
Before you start using cookies, there are a few things you should be aware of:
Since cookies are used to record information about your activities on a particular domain, they can onlybe read by the domain that created them
1.
A single domain cannot set more than twenty cookies, and each cookie is limited to a maximum size of 4KB
2.
A cookie usually possesses six attributes, of which only the first is mandatory. Here they are:name: the name of the cookievalue: the value of the cookieexpires: the date and time at which the cookie expirespath: the top-level directory on the domain from which cookie data can be accesseddomain: the domain for which the cookie is validsecure: a Boolean flag indicating whether the cookie should be transmitted only over a secure HTTPconnection
3.
More information on cookies can be obtained from Netscape, the people who originally invented them. Visithttp://www.netscape.com/newsref/std/cookie_spec.html for the Netscape cookie specification.
It's important to remember that, since cookies are stored on the user's hard drive, you as the developer havevery little control over them. If a user decides to turn off cookie support in his or her browser, your cookies will
simply not be saved. Therefore, avoid writing code that depends heavily on cookies; and have a backup planready in case cookie data cannot be retrieved from the client.
With that caveat out of the way, let's look at some simple cookie-handling code in PHP.
Meeting Old Friends
PHP offers a single function for cookie manipulation: setcookie(). This function allows you to read and write
cookie files, as demonstrated in the following example:
<?php
if (!isset($_COOKIE['visited'])) {
// if a cookie does not exist
// set it
setcookie("visited", "1", mktime()+86400, "/") or die("Could not set cookie");
echo "This is your first visit here today.";
}
else {
// if a cookie already exists
echo "Nice to see you again, old friend!";
}
?>
To see how this works, request the page above through your browser a couple of times. The first time around,because no cookie has yet been set, the first message will be displayed. On all subsequent attempts, becausethe cookie has already been set, the client will be recognized and the second message will be displayed. Notethat this works even if you terminate the browser instance, restart it and visit the page again - a markeddifference from what happened in the session examples you saw earlier.
The setcookie() function accepts six arguments: the name of the cookie, its value, its expiry date, the domain,
the path for which it is valid, and a Boolean value indicating its security state. As noted previously, only thename and value are mandatory, although the example above specifies both a top-level directory and an expirydate for the cookie (1 day) with the mktime() function, which works like the time() function described
previously.
Cookie values are automatically sent to PHP from the client, and converted to key-value pairs in the $_COOKIE
variable, a superglobal array similar to $_SESSION. Values can then be retrieved using standard associative array
notation, as in the example above. Note that, as with sessions, calls to setcookie() must take place before any
output is generated by the script, or else you'll see an error like this:
Form And Function
Here's another, slightly more complex example:
<?php
if (!isset($_POST['email'])) {
// if form has not been submitted
// display form
// if cookie already exists, pre-fill form field with cookie value
Warning: Cannot add header information - headers already sent by (output started at ... )
</html>
In this case, the value entered into the form is stored as a cookie called email, and automatically retrieved topre-fill the form field on all subsequent requests. This technique is frequently used by Web sites that require theuser to enter a login name and password; by automatically pre-filling the username field in the login box withthe value used in the last successful attempt, they save the user a few keystrokes.
This example also demonstrates how you can set more than one cookie for a domain, by calling setcookie()
multiple times. In the example above, the time at which the data was entered is stored as a second cookie, andused to calculate the time elapsed between successive entries.
To remove a cookie from the client, simply call setcookie() with the same syntax you used to originally set the
cookie, but an expiry date in the past. This will cause the cookie to be removed from the client system. Here'san example:
Read more about cookies and the setcookie() function at http://www.php.net/manual/en/features.cookies.php
and http://www.php.net/manual/en/function.setcookie.php.
Access Granted
As I said at the beginning of this tutorial, cookies and sessions are two different ways of making data"persistent" on the client. A session retains data for the duration of the session, while a cookie retains values foras long as you need it to. With that in mind, let's now look at an example that uses them both.
The application here is a simple user authentication system, where certain pages can only be viewed by userswho successfully log in to the system. Users who have not been authenticated with a valid password are deniedaccess to these "special" pages. The list of valid usernames and passwords is stored in a MySQL database, andPHP is used to verify a user's credentials and decide whether or not to grant access.
Assuming the MySQL database table looks like this
with a unique username field and a password field created with the SHA1() function, here's the PHP script that
does all the hard work:
<?php
if (isset($_POST['name']) || isset($_POST['pass'])) {
// form submitted
// check for required values
if (empty($_POST['name'])) {
die ("ERROR: Please enter username!");
}
if (empty($_POST['pass'])) {
die ("ERROR: Please enter password!");
}
// set server access variables
$host = "localhost";
$user = "test";
$pass = "test";
$db = "db2";
// open connection
$connection = mysql_connect($host, $user, $pass) or die ("Unable to connect!");
// select database
mysql_select_db($db) or die ("Unable to select database!");
// create query
$query = "SELECT * FROM users WHERE name = '" . $_POST['name'] . "' AND pass = SHA1('" .
$_POST['pass'] . "')";
// execute query
$result = mysql_query($query) or die ("Error in query: $query. " . mysql_error());
+-------+-----------------------------------------------+| name | pass |+-------+-----------------------------------------------+| sue | 9565d44fd0fe4db59f073eea1db70f3ea258e10b || harry | 6e74234b8b552685113b53c7bff0f386c8cef8cf || louis | 6817dda51b64b8190029490d2811a4d9cb9cd432 || sam | bd17f8243e771a57cfbb06aa9a82bbf09fd2d90b || james | 792ec9b44d432c947ac6775b2b52326e9d08512f |+-------+-----------------------------------------------+
else { // no result // authentication failed echo "ERROR: Incorrect username or password!"; } // free result set memory mysql_free_result($result); // close connection mysql_close($connection); } else { // no submission // display login form ?> <html> <head></head> <body> <center> <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"> Username <input type="text" name="name" value="<?php echo $_COOKIE['username']; ?>"> <p /> Password <input type="password" name="pass"> <p /> <input type="submit" name="submit" value="Log In"> </center> </body> </html> <?php }
?>
Here, the values entered into the login box are integrated into a MySQL SELECT query, which is executed on theuser table. If both username and password match, a single record will be returned, indicating that authenticationsucceeded; if they don't, no records will be returned, indicating that authentication failed.
Assuming authentication succeeds, a session is initialized, the $_SESSION['auth'] key is created and assigned
a value of Boolean true, and the username is stored in a cookie for next time. The cookie will remain valid for
30 days, and will be used to pre-fill the username field in the login box on the next login attempt.
Of course, this isn't enough by itself. While the script above performs authentication and initializes both asession and a cookie if the user's credentials are validated, a security check must also be carried out on each ofthe restricted pages. Without this check, any user could bypass the login screen and simply type in the exactURL to each page to view it.
Since it is clear from the previous script that the session variable $_SESSION['auth'] can only exist if the user's
credentials have been validated, it suffices to check for the presence of the $_SESSION['auth'] variable at the
top of each restricted page, and grant access if that check returns true. Here's how:
<?php
// start session
session_start();
if (!$_SESSION['auth'] == 1) {
// check if authentication was performed
// else die with error
die ("ERROR: Unauthorized access!");
}
else {
?>
<html>
<head></head>
<body>
This is a secure page. You can only see this if $_SESSION['auth'] = 1
</body>
</html>
<?php
}
?>
Pretty neat, huh? Only authenticated users will be able to see this page, because only their clients will have asession with the $_SESSION['auth'] variable in it. Everyone else will simply see an error message.
That's about it for this tutorial. In Part Eleven, I'll be telling you all about SimpleXML, the new XML processingtoolkit that comes bundled with PHP 5. Make sure you come back for that!
Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Tuesday, October 17, 2006
SECURITY PROBLEMS BUT GOOD RATING!7:54AM PDT � david_coallier
As we were looking for a good tutorial for beginners, we found this page, although, this is actually driving the
new developers to bad techniques.
For instance, in the "Access Granted" part, the author should defenatly change:$query = "SELECT * FROM users WHERE name = '" . $_POST['name'] . "' AND pass = SHA1('" . $_POST['pass']. "')";
to
$query = "SELECT * FROM users WHERE name = '" . mysql_real_escape_string($_POST['name']) . "' AND pass= SHA1('" . mysql_real_escape_string($_POST['pass']) . "')";
And also make sure you escape all your output by using or htmlentities() or htmlspecialchars(). So for instance:
At least you'd be somewhat sure that you cannot have XSS attacks, and yes I am aware that the htmlEntifity() function can use other encoding then utf8.
Moreover
if (empty($_POST['name'])) {die ("ERROR: Please enter username!");}if (empty($_POST['pass'])) {die ("ERROR: Please enter password!");}
I do not recommend to give the users that much information, I would go with something more like:if (strlen(trim($_POST['pass'])) == 0 || strlen(trim($_POST['name'])) == 0) {die ("ERROR: Some value is wrong.");} Tip: Security thru obscurity..
There is other things that could break in that snippet posted, but the rest is very good. Hope you all enjoyed!
I give 4.3/5
Wednesday, January 3, 2007
AND HOW TO MAKE THE LOGGED USER TO CHANGE HIS INFO6:50AM PST � Vladislav_m
This is wonderful part. But if a user log in, he will probably want to change some info (password for example).And how to make it?
Sunday, February 25, 2007
IS LOGIN SECURE FROM SQL INJECTION ATTACKS?10:22PM PST � William [unregistered]
I Master/anyone, can I ask about on how to secure the login page from sql injection attacks.
by Vikram Vaswani | 3 comments | Sunday, October 3, 2004
Easy PeasyThe Bad Old DaysPetting ZooSin CityThe Shape Of Things To ComeX Marks The SpotAn Evening At The Moulin Rouge
Easy Peasy
Unless you've been hiding in a cave for the last few years, you've heard about XML - it's the toolkit that moreand more Web publishers are switching to for content markup. You may even have seen an XML document inaction, complete with user-defined tags and markup, and you might have wondered how on earth one convertsthat tangled mess of code into human-readable content.
The answer is, not easily.
While PHP has included support for the two standard methods of parsing (read: making sense of) XML - SAX andDOM - since version 4.0, the complexity and inherent geekiness of these methods often turned off all but themost dedicated XML developers. All that has changed, however, with PHP 5.0, which introduces abrand-spanking-new XML extension named SimpleXML that takes all (and I do mean all) the pain out ofprocessing XML documents. Keep reading, and find out how.
The Bad Old Days
In order to understand why SimpleXML is so cool, a brief history lesson is in order.
In the days before SimpleXML, there were two ways of processing XML documents. The first, SAX or the Simple API for XML, involved traversing an XML document and calling specific functions as the parser encountereddifferent types of tags. For example, you might have called one function to process a starting tag, anotherfunction to process an ending tag, and a third function to process the data between them. The second, DOM or the Document Object Model, involved creating a tree representation of the XML document in memory, and thenusing tree-traversal methods to navigate it. Once a particular node of the tree was reached, the correspondingcontent could be retrieved and used.
Neither of these two approaches was particularly user-friendly: SAX required the developer to custom-craftevent handlers for each type of element encountered in an XML file, while the DOM approach used anobject-oriented paradigm which tended to throw developers off, in addition to being memory-intensive and thusinefficient with large XML documents. In the larger context also, PHP 4 used a number of different backendlibraries for each of its different XML extensions, leading to inconsistency in the way different XML extensionsworked and thus creating interoperability concerns (as well as a fair amount of confusion for developers).
With PHP 5.0, a concerted effort was made to fix this problem, by adopting the libxml2 library(http://www.xmlsoft.org/) as the standard library for all XML extensions and by getting the various XMLextensions to operate more consistently. The biggest change in the PHP 5 XML pantheon, though, is theSimpleXML extension developed by Sterling Hughes, Rob Richards and Marcus Börger, which attempts to makeparsing XML documents significantly more user-friendly than it was in PHP 4.
SimpleXML works by converting an XML document into an object, and then turning the elements within thatdocument into object properties which can be accessed using standard object notation. This makes it easy todrill down to an element at any level of the XML hierarchy to access its content. Repeated elements at the samelevel of the document tree are represented as arrays, while custom element collections can be created usingXPath location paths (of which, more later); these collections can then be processed using PHP's standard loopconstructs. Accessing element attributes is as simple as accessing the keys of an associative array - there'snothing new to learn, and no special code to write.
In order to use SimpleXML and PHP together, your PHP build must include support for SimpleXML. This support isenabled by default in both the UNIX and Windows versions of PHP 5. Read more about this athttp://www.php.net/manual/en/ref.simplexml.php. If you're a PHP 4 user, you're out of luck - SimpleXML is onlyavailable for PHP 5.
Petting Zoo
To see how SimpleXML works, consider the following XML file:
<?xml version="1.0"?>
<pet>
<name>Polly Parrot</name>
<age>3</age>
<species>parrot</species>
<parents>
<mother>Pia Parrot</mother>
<father>Peter Parrot</father>
</parents>
</pet>
Now, you need a way to get to the content enclosed between the <name>, <age>, <species> and <parents>
elements. With SimpleXML, it's a snap:
<?php
// set name of XML file
$file = "pet.xml";
// load file
$xml = simplexml_load_file($file) or die ("Unable to load XML file!");
The action begins with the simplexml_load_file() function, which accepts the path and name of the XML file
to be parsed. The result of parsing the file is a PHP object, whose properties correspond to the elements underthe root element. The character data within an element can then be accessed using standard object->property
notation, beginning with the root element and moving down the hierarchical path of the document.
Just as you can read, so also can you write. SimpleXML makes it easy to alter the contents of a particular XMLelement - simply assign a new value to the corresponding object property. Here's an example:
<?php
// set name of XML file
$file = "pet.xml";
// load file
$xml = simplexml_load_file($file) or die ("Unable to load XML file!");
// modify XML data
$xml->name = "Sammy Snail";
$xml->age = 4;
$xml->species = "snail";
$xml->parents->mother = "Sue Snail";
$xml->parents->father = "Sid Snail";
// write new data to file
file_put_contents($file, $xml->asXML());
?>
Here, the original XML file is first read in, and then the character data enclosed within each element is altered byassigning new values to the corresponding object property. The asXML() method, typically used to dump the
XML tree back out to the standard output device, is in this instance combined with the file_put_contents()
function to overwrite the original XML document with the new data.
Sin City
Repeated elements at the same level of the XML hierarchy are represented as array elements, and can beaccessed using numeric indices. To see how this works, consider the following XML file:
<?xml version="1.0"?>
<sins>
<sin>pride</sin>
<sin>envy</sin>
<sin>anger</sin>
<sin>greed</sin>
<sin>sloth</sin>
<sin>gluttony</sin>
<sin>lust</sin>
</sins>
Here's the PHP script that reads it and retrieves the data from it:
<?php
// set name of XML file
$file = "sins.xml";
// load file
$xml = simplexml_load_file($file) or die ("Unable to load XML file!");
// access each <sin>
echo $xml->sin[0] . "\n";
echo $xml->sin[1] . "\n";
echo $xml->sin[2] . "\n";
echo $xml->sin[3] . "\n";
echo $xml->sin[4] . "\n";
echo $xml->sin[5] . "\n";
echo $xml->sin[6] . "\n";
?>
If you'd prefer, you can even iterate over the collection with a foreach() loop, as in this next, equivalent listing:
<?php
// set name of XML file
$file = "sins.xml";
// load file
$xml = simplexml_load_file($file) or die ("Unable to load XML file!");
// iterate over <sin> element collection
foreach ($xml->sin as $sin) {
echo "$sin\n";
}
?>
The Shape Of Things To Come
SimpleXML handles element attributes as transparently as it does elements and their content. Attribute-valuepairs are represented as members of a PHP associative array, and can be accessed like regular array elements.To see how this works, take a look at this script:
<?php
// create XML string
$str = <<< XML
<?xml version="1.0"?>
<shapes>
<shape type="circle" radius="2" />
<shape type="rectangle" length="5" width="2" />
<shape type="square" length="7" />
</shapes>
XML;
// load string
$xml = simplexml_load_string($str) or die ("Unable to load XML string!");
Unlike previous examples, which used an external XML file, this one creates the XML dynamically and loads itinto SimpleXML with the simplexml_load_string() method. The XML is then parsed with a foreach() loop,
and the area for each shape calculated on the basis of the value of each <shape> element's type attribute. The
listing above demonstrates how attribute values can be accessed as keys of the attribute array associated witheach element property.
X Marks The Spot
SimpleXML also supports custom element collections, through XPath location paths. For those of you new toXML, XPath is a standard addressing mechanism for an XML document, allowing developers to access collectionsof elements, attributes or text nodes within a document. Read more about XPath athttp://www.w3.org/TR/xpath.html and http://www.melonfire.com/community/columns/trog/article.php?id=83.
To see how this works, consider the following XML document:
<?xml version="1.0"?>
<ingredients>
<item>
<desc>Boneless chicken breasts</desc>
<quantity>2</quantity>
</item>
<item>
<desc>Chopped onions</desc>
<quantity>2</quantity>
</item>
<item>
<desc>Ginger</desc>
<quantity>1</quantity>
</item>
<item>
<desc>Garlic</desc>
<quantity>1</quantity>
</item>
<item>
<desc>Red chili powder</desc>
<quantity>1</quantity>
</item>
<item>
<desc>Coriander seeds</desc>
<quantity>1</quantity>
</item>
<item>
<desc>Lime juice</desc>
<quantity>2</quantity>
</item>
</ingredients>
Now, let's suppose you want to print all the <desc> elements. You could do it by iterating over the array of
<item> elements, as discussed earlier...or you could just create a custom collection of only the <desc> elements
with the xpath() method, and iterate over that instead:
<?php
// set name of XML file
$file = "ingredients.xml";
// load file
$xml = simplexml_load_file($file) or die ("Unable to load XML file!");
// get all the <desc> elements and print
foreach ($xml->xpath('//desc') as $desc) {
echo "$desc\n";
}
?>
Using XPath, you can get even fancier than this - for example, by creating a collection of only those <desc>
elements whose corresponding quantities are two or more.
<?php
// set name of XML file
$file = "ingredients.xml";
// load file
$xml = simplexml_load_file($file) or die ("Unable to load XML file!");
// get all the <desc> elements and print
foreach ($xml->xpath('//item[quantity > 1]/desc') as $desc) {
echo "$desc\n";
}
?>
Without XPath, accomplishing this would be far more complicated than the five lines of code above...try it foryourself and see!
An Evening At The Moulin Rouge
Now that you've seen what XPath can do, let's wrap this up with an example of how you might actually use it.Let's suppose you have a bunch of movie reviews marked up in XML, like this:
<?xml version="1.0"?>
<review id="57" category="2">
<title>Moulin Rouge</title>
<teaser>
Baz Luhrmann's over-the-top vision of Paris at the turn of the century
is witty, sexy...and completely unforgettable
</teaser>
<cast>
<person>Nicole Kidman</person>
<person>Ewan McGregor</person>
<person>John Leguizamo</person>
<person>Jim Broadbent</person>
<person>Richard Roxburgh</person>
</cast>
<director>Baz Luhrmann</director>
<duration>120</duration>
<genre>Romance/Comedy</genre>
<year>2001</year>
<body>
A stylishly spectacular extravaganza, Moulin Rouge is hard to
categorize; it is, at different times, a love story, a costume drama,
a musical, and a comedy. Director Baz Luhrmann (well-known for the
very hip William Shakespeare's Romeo + Juliet) has taken some simple
themes - love, jealousy and obsession - and done something completely
new and different with them by setting them to music.
</body>
<rating>5</rating>
</review>
Now, you want to display this review on your Web site. So, you need a PHP script to extract the data from thisfile and place it in the appropriate locations in an HTML template. With everything you've learned so far, this is asnap...as the code below illustrates:
<?php
// set name of XML file
// normally this would come through GET
// it's hard-wired here for simplicity
$file = "57.xml";
// load file
$xml = simplexml_load_file($file) or die ("Unable to load XML file!");
That's about all for the moment. In Part Twelve of PHP 101, I'll be telling you all about the new exceptionhandling model in PHP 5, showing you how you can use it to catch your scripts before they crash and burn. Seeyou there!
Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Thursday, September 14, 2006
CREATING/WRITING NEW FILES8:04PM PDT � mercury7
Whilst I found this tutorial very useful I regret the lack of a code example to create & write to a new file.
I am able to write to a new file if I create it seperately and it contains all the required XML tags. However I'd like to know if its possible to write the file creation (like the string creation in 'The Shape Of Things To Come') into the script so the file is created on the fly & then written to.
Any help on this that could be posted to this coment page would be appreciated.
Thanks
Mark
Thursday, October 19, 2006
HELLO MARK, CREATING A .XML FILE3:13AM PDT � alexcory
Hey, My name is Alex.
I just got hired by Dominion Enterprises as a php developer and they directed me to these tutorials. I noticedyour comment and I may have a solution to your problem (even though its been maybe a month or so)
anyway take a look at what I got below, this is for writing a .html file, I'm assuming you can use this for .xml too. I work under php version 5 so I don't know if it works with earlier versions.
Here is the code:
$filename = "testfile.html";$contents = <<< FILE_DONE<html><head><title>testfile</title></head><body>This is a test file for .html code</body></html>FILE_DONE;
file_put_contents($filename, $contents) or die('could not write to file');
//END CODE
the <<< FILE_DONE is an interesting way of combining a set of tags/commands/strings all at once. it will set$contents equal to everything until it sees another FILE_DONE with a ; at the end. FILE_DONE can also bechanged to ALL_DONE or any other name so long as you end with that name.
WARNING!!! using this method the ending FILE_DONE; MUST be set all the way to the left of your code, if it is tabbed over in any way it will provide a parse error.
I hope this helps with your problem, c ya later.
--AlexCory
Thursday, May 24, 2007
ACESSING ROOT ELEMENT ATTRIBUTES5:28PM PDT � nickweavers
So, in the "An Evening At The Moulin Rouge" example, how would you echo the review id and categoryattributes directly? I have seen it done using the attributes() method in a foreach loop something like this:
// Load up the root element attributesforeach($xml->attributes() as $name=>$attr) {$res[$name]=$attr;}
However, I would like to know if I can use a direct path?
Thanks,Nick.
PHP 101 (part 12): Bugging Out - Part 1All Skill Levels PHP101 PHP5 Tutorials
by Vikram Vaswani | 1 comment | Sunday, January 30, 2005
Fire-Proofing Your CodeRogues GalleryEarly WarningRolling Your OwnPHP 101 (part 12): Bugging Out - Part 2
Fire-Proofing Your Code
Even the best developers make mistakes sometimes. That's why most programming languages - including PHP -come with built-in capabilities to catch errors and take remedial action. This action can be as simple asdisplaying an error message, or as complex as sending the site administrator an email with a complete stacktrace.
To make it easier to do this, PHP comes with a full-featured error handling API that can be used to trap andresolve errors. In addition to deciding which types of errors a user sees, you can also replace the built-in errorhandling mechanism with your own custom (and usually more creative) functions. If you're using PHP 5, you geta bonus: a spanking-new exception model, which lets you wrap your code in Java-like try-catch() blocks for
more efficient error handling.
In this edition of PHP 101, I'm going to discuss all these things, giving you a crash course in how to adderror-handling to your PHP application. Keep reading - this is pretty cool stuff!
Rogues Gallery
Before we get into the nitty-gritty of how to write an error handler, you need to know a little theory.
Normally, when a PHP script encounters an error, it displays a message indicating the cause of the error andmay also (depending on how serious the error is) terminate script execution. Now, while this behaviour isacceptable during the development phase, it cannot continue once a PHP application has been released to actualusers. In "live" situations, it is unprofessional to display cryptic error messages (which are usuallyincomprehensible to non-technical users); it is more professional to intercept these errors and either resolvethem (if resolution is possible), or notify the user with an easily-understood error message (if not).
There are three basic types of runtime errors in PHP:
Notices: These are trivial, non-critical errors that PHP encounters while executing a script - for example,accessing a variable that has not yet been defined. By default, such errors are not displayed to the user atall - although, as you will see, you can change this default behaviour.
1.
Warnings: These are more serious errors - for example, attempting to include() a file which does not
exist. By default, these errors are displayed to the user, but they do not result in script termination.
2.
Fatal errors: These are critical errors - for example, instantiating an object of a non-existent class, orcalling a non-existent function. These errors cause the immediate termination of the script, and PHP'sdefault behaviour is to display them to the user when they take place.
3.
It should be noted that a syntax error in a PHP script - for example, a missing brace or semi-colon - is treated asa fatal error and results in script termination. That's why, if you forget a semi-colon at the end of one of yourPHP statements, PHP will refuse to execute your script until you correct the mistake.
PHP errors can be generated by the Zend engine, by PHP built-in functions, or by user-defined functions. Theymay occur at startup, at parse-time, at compile-time or at run-time. Internally, these variations are representedby twelve different error types (as of PHP 5), and you can read about them athttp://www.php.net/manual/en/ref.errorfunc.php. Named constants like E_NOTICE and E_USER_ERROR provide a
convenient way to reference the different error types.
A quick tip here: most of the time, you'll be worrying about run-time errors (E_NOTICE, E_WARNING and E_ERROR)
and user-triggered errors (E_USER_NOTICE, E_USER_WARNING and E_USER_ERROR). During the debug phase, you
can use the shortcut E_ALL type to see all fatal and non-fatal errors generated by your script, and in PHP 5 you
might also want to use the new E_STRICT error type to view errors that affect the forward compatibility of your
code.
Early Warning
With the theory out of the way, let's now apply it to some examples. Consider the following code snippet:
<?php
// initialize the $string variable
$string = 'a string';
// explode() a string
// this will generate a warning or E_WARNING because the number of arguments to explode() is
incorrect
explode($string);
?>
If you run this script, you'll get a non-fatal error (E_WARNING), which means that if you had statements following
the call to explode(), they would still get executed. Try it for yourself and see!
To generate a fatal error, you need to put in a bit more work. Take a look at this:
<?php
// call a non-existent function
// this will generate a fatal error (E_ERROR)
callMeJoe();
?>
Here, the call to a non-existent function trips all of PHP's alarm wires and generates a fatal error, whichimmediately stops script execution.
Now, here's the interesting bit. You can control which errors are displayed to the user, by using a built-in PHPfunction called error_reporting(). This function accepts a named constant, and tells the script to report only
errors that match that type. To see this in action, consider the following rewrite of one of the earlier scripts to"hide" non-fatal errors:
<?php
// report only fatal errors
error_reporting(E_ERROR);
// initialize the $string variable
$string = 'string';
// attempt to explode() a string
// this will not generate a warning because only fatal errors are reported
explode($string);
?>
In this case, when the script executes, no warning will be generated even though the call to explode() contains
one less argument than it should.
You can use a similar technique to turn off the display of fatal errors:
<?php
// report no fatal errors
error_reporting(~E_ERROR);
// call a non-existent function
callMeJoe();
?>
Keep in mind, though, that just because the error isn't being reported doesn't mean it isn't occurring. Althoughthe script above will not display a visible error message, script execution will still stop at the point of error andstatements subsequent to that point will not be executed. error_reporting() gives you control over which
errors are displayed; it doesn't prevent the errors themselves.
Note that there are further settings within php.ini that should be used on production sites. You can (and should)turn off display_errors, stipulate an error_log file and switch on log_errors.
Note also that the approach used above to hide error messages, although extremely simple, is notrecommended for general use. It is poor programming practice to trap all errors, regardless of type, and ignorethem; it is far better - and more professional - to anticipate the likely errors ahead of time, and write defensivecode that watches for them and handles them appropriately. This will prevent your users from findingthemselves staring at an unexplained blank page when something goes wrong.
Rolling Your Own
With this in mind, let's talk a little bit about changing the way errors are handled. Consider a typical PHP errormessage: it lists the error type, a descriptive message, and the name of the script that generated the error.Most of the time, this is more than sufficient... but what if your boss is a demanding customer, and insists thatthere must be a "better way"?
Well, there is. It's a little function called set_error_handler(), and it allows you to divert all PHP errors to a
custom function that you've defined, instead of sending them to the default handler. This custom function mustbe capable of accepting a minimum of two mandatory arguments (the error type and corresponding descriptivemessage) and up to three additional arguments (the file name and line number where the error occurred and adump of the variable space at the time of error).
The following example might make this clearer:
<?php
// define a custom error handler
set_error_handler('oops');
// initialize the $string variable
$string = 'a string';
// explode() a string
// this will generate a warning because the number of arguments to explode() is incorrect
// the error will be caught by the custom error handler
explode($string);
// custom error handler
function oops($type, $msg, $file, $line, $context) {
echo "<h1>Error!</h1>";
echo "An error occurred while executing this script. Please contact the <a
echo "Here is the information provided by the script:";
echo "<hr><pre>";
echo "Error code: $type<br />";
echo "Error message: $msg<br />";
echo "Script name and line number of error: $file:$line<br />";
$variable_state = array_pop($context);
echo "Variable state when error occurred: "; print_r($variable_state); echo "</pre><hr>"; }
?>
The set_error_handler() function tells the script that all errors are to be routed to my user-defined oops()
function. This function is set up to accept five arguments: error type, message, file name, line number, and anarray containing a lot of information about the context that the error occurred in (including server and platform,as well as script information). The final element of the context array contains the current value of the guiltyvariable. These arguments are then used to create an error page that is friendlier and more informative thanPHP's standard one-line error message.
You can use this custom error handler to alter the error message the user sees, on the basis of the error type.Take a look at the next example, which demonstrates this technique:
<?php
// define a custom error handler
set_error_handler('oops');
// initialize $string variable
$string = 'a string';
// this will generate a warning
explode($string);
// custom error handler
function oops($type, $msg, $file, $line, $context) {
switch ($type) {
// notices
case E_NOTICE:
// do nothing
break;
// warnings
case E_WARNING:
// report error
print "Non-fatal error on line $line of $file: $msg <br />";
break;
// other
default:
print "Error of type $type on line $line of $file: $msg <br />";
break;
}
}
?>
Note that certain error types can't be handled in this way. For example, a fatal E_ERROR will prevent the PHP
script from continuing, therefore it can never reach a user-created error-handling mechanism. Seehttp://www.php.net/set-error-handler for more information on this.
PHP 101 (part 12): Bugging Out - Part 2
Copyright Melonfire, 2004 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Tuesday, May 29, 2007
!1:44PM PDT � andyzzz
As always great info. Thank you.
PHP 101 (part 13): The Trashman Cometh - Part 1All Skill Levels PHP101 PHP5 Tutorials
by Vikram Vaswani | 0 comments | Sunday, February 27, 2005
Waiting to ExhaleAn Empty Vessel...Not My TypeThe Dating Game
PHP 101 (part 13): The Trashman Cometh - Part 2
Waiting to Exhale
Maybe you've heard the term GIGO before.
If you haven't, it stands for Garbage In, Garbage Out, and it's a basic fact of computer programming: if youfeed your program bad input, you're almost certainly going to get bad output. And no matter which way you cutit, bad output is not a Good Thing for a programmer who wants to get noticed.
In case you think I'm exaggerating, let me give you a simple example. Consider an online loan calculator thatallows a user to input a desired loan amount, finance term and interest rate. Let's assume that the applicationdoesn't include any error checks, and that the user decides to enter that magic number, 0, into the Term field.
You can imagine the result. After a few internal calculations the application will end up attempting to divide thetotal amount payable by zero. The slew of ugly error messages that follow don't really bear discussion, but it'sworth noting that they could have been avoided had the developer had the foresight to include an input validation routine when designing the application.
The moral of this story? If you're serious about using PHP for web development, one of the most importantthings you must learn is how to validate user input and deal with potentially unsafe data. Such input verificationis one of the most important safeguards a developer can build into an application, and a failure to do this cansnowball into serious problems, or even cause your application to break when it encounters invalid or corruptdata.
That's where this edition of PHP 101 comes in. Over the next few paragraphs, I'm going to show you some basictricks to validate user input, catch "bad" data before it corrupts your calculations and databases, and provideuser notification in a gentle, understandable and non-threatening way. To prepare for this exercise, I suggestyou spin up a CD of John Lennon singing 'Imagine', fill your heart with peace and goodwill towards all men, andtake a few deep, calming breaths. Once you've exhaled, we can get going.
An Empty Vessel...
This tutorial assumes that the user input to be validated arrives through a web form. This is not the only way aPHP script can get user data; however, it is the most common way. If your PHP application needs to validatecommand-line input, I'd recommend you read my article on the PEAR Console_Getopt class, available for your
perusal at http://www.zend.com/pear/tutorials/Console-Getopt.php.
It's common practice to use client-side scripting languages such as JavaScript or VBScript for client-side formvalidation. However, this type of client-side validation is not foolproof. You're not in control of the client, so if auser turns off JavaScript in his or her browser, all your efforts to ensure that the user does not enter irrelevantdata become - well - irrelevant. That's why most experienced developers use both client-side and server-sidevalidation. Server-side validation involves checking the values submitted to the server through a PHP script, andtaking appropriate action when the input is incorrect.
Let's begin with the most commonly found input error: a required form field that is missing its value. Take alook at this example:
$connection = mysql_connect($host, $user, $pass) or die('Unable to connect!');
// select database
mysql_select_db($db) or die('Unable to select database!');
// create query
$query = 'INSERT INTO orders (filling) VALUES ("$filling")';
// execute query $result = mysql_query($query) or die("Error in query: $query. ".mysql_error());
// close connection mysql_close($connection);
// display message echo "Your {$_POST['filling']} sandwich is coming right up!";}?></body></html>
It's clear from the example above that submitting the form without entering any data will result in an emptyrecord being added to the database (assuming no NOT NULL constraints on the target table). To avoid this, it's
important to verify that the form does, in fact, contain valid data, and only then perform the INSERT query.
$connection = mysql_connect($host, $user, $pass) or die('Unable to connect!');
// select database
mysql_select_db($db) or die('Unable to select database!');
// create query
$query = 'INSERT INTO orders (filling) VALUES ("$filling")';
// execute query
$result = mysql_query($query) or die("Error in query: $query. ".mysql_error());
// close connection
mysql_close($connection);
// display message
echo "Your {$_POST['filling']} sandwich is coming right up!";
}
?>
</body>
</html>
The error check here is both simple and logical: the trim() function is used to trim leading and trailing spaces
from the field value, which is then compared with an empty string. If the match is true, the field was submittedempty, and the script dies with an error message before MySQL comes into the picture.
A common mistake, especially among newbies, is to replace the isset() and trim() combination with a call to
PHP's empty() function, which tells you if a variable is empty. This isn't usually a good idea, because empty()
has a fatal flaw: it'll return true even if a variable contains the number 0. The following simple exampleillustrates this:
<?php
// no data, returns empty
$data = '';
echo empty($data) ? "$data is empty" : "$data is not empty";
echo "<br />\n";
// some data, returns not empty
$data = '1';
echo empty($data) ? "$data is empty" : "$data is not empty";
echo "<br />\n";
// some data, returns empty$data = '0';echo empty($data) ? "$data is empty" : "$data is not empty";
?>
So, if your form field is only allowed to hold non-empty, non-zero data, empty() is a good choice for validating
it. But if the range of valid values for your field includes the number 0, stick with the isset() and trim()
combination instead.
Not My Type
So now you know how to catch the most basic error - missing data - and stop script processing before anydamage takes place. But what if the data's present, but of the wrong type or size? Your 'missing values' testwon't be triggered, but your calculations and database could still be affected. Obviously, then, you need to add afurther layer of security, wherein the data type of the user input is also verified.
How many sandwiches would you like? (min 1, max 9)
<br />
<input type = 'text' name = 'quantity'>
<br />
<input type = 'submit' name = 'submit' value = 'Save'>
</form>
<?php
}
else {
// check for required data
// die if absent
if (!isset($_POST['quantity']) || trim($_POST['quantity']) == '') {
die ("ERROR: Can't make 'em if you don't say how many!");
}
// check if input is a number
if (!is_numeric($_POST['quantity'])) {
die ("ERROR: Whatever you just said isn't a number!");
}
// check if input is an integer
if (intval($_POST['quantity']) != $_POST['quantity']) {
die ("ERROR: Can't do halves, quarters or thirds... I'd lose my job!");
}
// check if input is in the range 1-9
if (($_POST['quantity'] < 1) || ($_POST['quantity'] > 9)) {
die ('ERROR: I can only make between 1 and 9 sandwiches per order!');
}
// process the data
echo "I'm making you {$_POST['quantity']} sandwiches. Hope you can eat them all!";
}
?>
</body>
</html>
Notice that once I've established that the field contains some data, I've added a bunch of tests to make sure itmeets data type and range constraints. First, I've checked if the value is numeric, with the is_numeric()
function. This function tests a string to see if it is a numeric string - that is, a string consisting only of numbers.
Assuming what you've got is a number, the next step is to make sure it's an integer value between 1 and 9. Totest if it's an integer, I've used the intval() function to extract the integer part of the value, and tested it
against the value itself. Float values (such as 2.5) will fail this test; integer values will pass it. The final stepbefore green-lighting the value is to see if it falls between 1 and 9. This is easy to accomplish with a couple ofinequality tests.
Whilst on the topic, it's also worth mentioning the strlen() function, which returns the length of a string. This
can come in handy to make sure that form input doesn't exceed a particular length. The following exampleshows how:
<input type = 'submit' name = 'submit' value = 'Save'>
</form>
<?php}else { // check for required data // die if absent if (!isset($_POST['nick']) || trim($_POST['nick']) == '') { die ('ERROR: Come on, surely you can think of a nickname! How about Pooky?'); }
// check if input is of the right length if (!(strlen($_POST['nick']) >= 6 && strlen($_POST['nick']) <= 10)) { die ("ERROR: That's either too long or too short!"); }
// process the data echo "I'll accept the nickname {$_POST['nick']}, seeing as it's you!";}?></body></html>
Here, the strlen() function is used to verify that the string input is neither too long nor too short. It's also a
handy way to make sure that input data satisfies the field length constraints of your database. For example, ifyou have a MySQL VARCHAR(10) field, strings over 10 characters in length will be truncated. The strlen()
function can serve as an early warning system in such cases, notifying the user of the length mismatch andavoiding data corruption.
The Dating Game
Validating dates is another important aspect of input validation. It's all too easy, given a series of drop-downlist boxes or free-form text fields, for a user to select a date like 29-Feb-2005 or 31-Apr-2005, neither of which
is valid. Therefore, it's important to check that date values provided by the user are valid before using them in acalculation.
In PHP, this task is significantly simpler than in other languages, because of the checkdate() function. This
function accepts three arguments - month, day and year - and returns a Boolean value indicating whether or notthe date is valid. The following example demonstrates it in action:
<input type = 'submit' name = 'submit' value = 'Save'>
</form>
<?php
}
else {
// check if date is valid
if (!checkdate($_POST['month'], $_POST['day'], $_POST['year'])) {
die("ERROR: The date {$_POST['day']}-{$_POST['month']}-{$_POST['year']} doesn't
exist!");
}
// process the data
echo "You entered {$_POST['day']}-{$_POST['month']}-{$_POST['year']} - which is a valid
date.";
}
?>
</body>
</html>
Try entering an invalid date, and see how PHP calls you on it. Ain't that cool?
If you're storing date input in a MySQL table, it's interesting to note that MySQL does not perform any rigorous date verification of its own before accepting a DATE, DATETIME or TIMESTAMP value. Instead, it expects the
developer to build date verification into the application itself. The most that MySQL will do, if it encounters anobviously illegal value, is convert the date to a zero value - not very helpful at all! Read more about this athttp://dev.mysql.com/doc/mysql/en/datetime.html.
While we're on the topic, let's talk a little bit more about multiple-choice form elements like drop-down list boxes and radio buttons. In cases where it's mandatory to make a choice, a developer must verify that at leastone of the available options has been selected by the user. This mainly involves clever use of the isset() and -
for multi-select list boxes - the is_array() and sizeof() functions. The next example illustrates this:
<input type = 'radio' name = 'base' value = 'thin and crispy'>Thin and crispy
<input type = 'radio' name = 'base' value = 'deep-dish'>Deep-dish
<br />
Cheese:
<br />
<select name = 'cheese'>
<option value = 'mozzarella'>Mozzarella</option>
<option value = 'parmesan'>Parmesan</option>
<option value = 'gruyere'>Gruyere</option>
</select>
<br />
Toppings:
<br />
<select multiple name = 'toppings[]'>
<option value = 'tomatoes'>Tomatoes</option>
<option value = 'olives'>Olives</option>
<option value = 'pepperoni'>Pepperoni</option>
<option value = 'onions'>Onions</option>
<option value = 'peppers'>Peppers</option>
<option value = 'sausage'>Sausage</option>
<option value = 'anchovies'>Anchovies</option>
</select>
<br />
<input type = 'submit' name = 'submit' value = 'Save'>
</form>
<?php
}
else {
// check radio button
if (!isset($_POST['base'])) {
die('You must select a base for the pizza');
}
// check list box
if (!isset($_POST['cheese'])) {
die('You must select a cheese for the pizza');
}
// check multi-select box
if (!is_array($_POST['toppings']) || sizeof($_POST['toppings']) < 1) {
die('You must select at least one topping for the pizza');
}
// process the data
echo "One {$_POST['base']} {$_POST['cheese']} pizza with ";
foreach ($_POST['toppings'] as $topping) echo $topping.", ";
echo "coming up!";
}
?>
</body>
</html>
Nothing to tax your brain too much here - the isset() function merely checks to see if at least one of a set of
options has been selected, and prints an error message if this is not the case. Notice how the multi-select listbox is validated: when the form is submitted, selections made here are placed in an array, and PHP'sis_array() and sizeof() functions are used to test that array and ensure that it contains at least one element.
PHP 101 (part 13): The Trashman Cometh - Part 2
Copyright Melonfire, 2005 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
PHP 101 (part 14): Going to the Polls - Part 1All Skill Levels PHP101 PHP5 Tutorials
by Vikram Vaswani | 1 comment | Tuesday, March 8, 2005
The Real WorldBurning QuestionsDesigner DatabasesRocking the Vote
PHP 101 (part 14): Going to the Polls - Part 2
The Real World
In the course of this series, I've taken you on a tour of PHP, teaching you everything you need to know to getstarted with this extremely powerful toolkit. You've learned how to process arrays, write functions, constructobjects, and throw exceptions. You've also learned how to read user input from forms, search databases, anduse cookies and sessions to maintain state. You're no longer the timid PHP newbie you used to be, but a boldand powerful PHP warrior, ready to take on anything the world (or your boss) throws at you...
There's only one drawback. Sure, you have all the weaponry... but you haven't ever used it in the real world.That's where these concluding segments of PHP 101 come in.
Over the final two chapters of this tutorial, I'm going to guide you through the process of creating two real-worldPHP applications. Not only will this introduce you to practical application development with PHP, but it will alsogive you an opportunity to try out all the theory you've imbibed over the past weeks.
Drivers, start your engines!
Burning Questions
The first application is fairly simple. It's a polling system for a web site, one which allows you to quicklymeasure what your visitors think about controversial issues (Kerry versus Bush, to-mah-to versus to-mae-to, that kind of thing). This online polling mechanism is fairly popular, because it lets you find out what your visitorsare thinking, and makes your web site more dynamic and interactive.
I'm sure you've seen such a system in action on many web portals, and have a fairly clear mind's-eye picture ofhow it works. Nevertheless, it's good practice to write down exactly what the end product is supposed to dobefore you begin writing even a single line of code (geeks call this defining requirements).
There needs to be a mechanism by which the user can view a question, and then select from a list ofpossible answers. This "vote" then needs to be captured by the system, and added to the existing tally ofvotes for that question.
1.
There needs to be a way for the site administrator to add new questions, or delete old ones. A MySQLdatabase is a good place to store these questions and answers, but the administrator may not necessarilybe proficient enough in SQL to change this data manually. Therefore, a form-based interface should beprovided, to make the task simple and error-free.
2.
Obviously, there also needs to be a way to view reports of the votes submitted for each question and itsanswers. The report would contain a count of the total votes registered for a question, as well as abreakdown of the votes each answer received.
3.
An important question here is: Does it make sense to fix the number of available choices for each question? Inmy opinion, it doesn't, because the number of available choices is likely to change with each question. It's betterto leave this number variable, and to allow the poll administrator to add as many choices per question asappropriate. We can, however, define an upper limit on the number of possible choices for each question - forargument's sake let's say five.With this basic outline in mind, the next step is to design a database that supports these requirements.
Designer Databases
This is a good time for you to download the source code for this application, so that you can refer to it throughout this tutorial. (Note that you will need a MySQL server and a PHP-capable Web server to run thiscode.)
Here's the database which I'll be using for this application, stored in db.sql:
As you can see, this is pretty simple: one table for the questions, and one for the answers. The two tables arelinked to each other by means of the qid field. With this structure, it's actually possible to have an infinite
numbers of answers to each question. (This is not what we want - we'd prefer this number to be five or less -but the logic to implement this rule is better placed at the application layer than at the database layer).To get things started, and to give you a better idea of how this structure plays in real life, let's INSERT a
question into the database, together with three possible responses:
## Table structure for table `questions`#CREATE TABLE `questions` ( `qid` tinyint(3) unsigned NOT NULL auto_increment, `qtitle` varchar(255) NOT NULL default '', `qdate` date NOT NULL default '0000-00-00', PRIMARY KEY (`qid`));
## Table structure for table `answers`#CREATE TABLE `answers` ( `aid` tinyint(3) unsigned NOT NULL auto_increment, `qid` tinyint(4) NOT NULL default '0', `atitle` varchar(255) NOT NULL default '', `acount` int(11) NOT NULL default '0', PRIMARY KEY (`aid`));
Alternatively, you could create a new database and type source db.sql from the command prompt to load the
table structures and data directly.
Rocking the Vote
With the database taken care of, it's time to put together the web pages that the user sees. The first of these isuser.php, which connects to the database to get the latest poll question and displays it together with all itspossible responses. Take a look:
<html>
<head><basefont face = 'Arial'></head>
<body>
<?php
// include configuration file
include('config.php');
// open database connection
$connection = mysql_connect($host, $user, $pass) or die('ERROR: Unable to connect!');
// select database
mysql_select_db($db) or die('ERROR: Unable to select database!');
// generate and execute query
$query = "SELECT qid, qtitle FROM questions ORDER BY qdate DESC LIMIT 0, 1";
$result = mysql_query($query) or die("ERROR: $query.".mysql_error());
// if records are present
if (mysql_num_rows($result) > 0) {
$row = mysql_fetch_object($result);
// get question ID and title
$qid = $row->qid;
echo '<h2>'.$row->qtitle .'</h2>';
echo "<form method = post action = 'user_submit.php'>";
// get possible answers using question ID
$query = "SELECT aid, atitle FROM answers WHERE qid = '$qid'";
$result = mysql_query($query) or die("ERROR: $query.".mysql_error());
echo "<input type = hidden name = qid value = '".$qid."'>";
echo "<input type = submit name = submit value = 'Vote!'>";
}
echo '</form>';
}
// if no records present, display message
else {
echo '<font size="-1">No questions currently configured</font>';
}
// close connection
mysql_close($connection);
?>
</body>
</html>
Pay special attention to the SQL query I'm running: I'm using the ORDER BY, DESC and LIMIT keywords to
ensure that I get the latest record (question) from the questions table. Once the query returns a result, the
record ID is used to get the corresponding answer list from the answers table. A while() loop is then used to
print the answers as a series of radio buttons. The record ID corresponding to each answer is attached to itsradio button; when the form is submitted, this identifier will be used to ensure that the correct counter isupdated.
Note that if the database is empty, an error message is displayed. In this example, we've already inserted onequestion into the database, so you won't see it at all; however, it's good programming practice to ensure that alleventualities are accounted for, even the ones that don't occur that very often.
The file config.php included at the top of the script contains the access parameters for the MySQL database. Thisdata has been placed in a separate file to make it easy to change it if you move the application to a new server.Take a look inside:
<?php
// database access parameters
INSERT INTO `questions` VALUES (1, 'What version of PHP are you using?', '2004-10-15');INSERT INTO `answers` VALUES (1, 1, 'PHP 3.x', 0);INSERT INTO `answers` VALUES (2, 1, 'PHP 4.x', 0);INSERT INTO `answers` VALUES (3, 1, 'PHP 5.x', 0);
Okay, now you've got the poll displayed. Users are lining up to participate, and clicks are being generated by themillions. What do you do with them?
The answer lies in the script that gets activated when a user casts a vote and submits the form describedearlier. This script, user_submit.php, takes care of updating the vote counter for the appropriatequestion/answer combination. Take a look:
<html>
<head><basefont face = 'Arial'></head>
<body>
<?php
if (isset($_POST['submit'])) {
if (!isset($_POST['aid'])) {
die('ERROR: Please select one of the available choices');
}
// include configuration file
include('config.php');
// open database connection
$connection = mysql_connect($host, $user, $pass) or die('ERROR: Unable to connect!');
// select database
mysql_select_db($db) or die('ERROR: Unable to select database!');
// update vote counter
$query = "UPDATE answers SET acount = acount + 1 WHERE aid = ".$_POST['aid']." AND qid =
".$_POST['qid'];
$result = mysql_query($query) or die("ERROR: $query. ".mysql_error());
// close connection
mysql_close($connection);
// print success message
echo 'Your vote was successfully registered!';
}
else {
die('ERROR: Data not correctly submitted');
}
?>
</body>
</html>
This script first checks to ensure that an answer has been selected, by verifying the presence of the answer ID$_POST['aid']. Assuming the ID is present, the script updates the database to reflect the new vote and
displays an appropriate message.
Now, flip back through your notebook and look at the initial requirement list. Yup, you can cross off Item #1.Onwards to Item #2...
PHP 101 (part 14): Going to the Polls - Part 2
Copyright Melonfire, 2005 (http://www.melonfire.com). All rights reserved.
Comments
Add Comment
Sunday, March 25, 2007
BROKEN LINKS10:35PM PDT � Anonymous User [unregistered]
There are some broken links as mentioned under:
http://devzone.zend.com/node/view/id/php-14.zip
In some of the anchors provided in the 15 part series, the anchors are provided as .............../id/php-*.
Whereas the anchors on the main page of the 15 part series, is correctly linked as
http://devzone.zend.com/node/view/id/###
PHP 101 (part 15): No News is Good News All Skill Levels PHP101 PHP5 Tutorials
by Vikram Vaswani | 0 comments | Saturday, June 4, 2005
A Difficult Choice Alphabet Soup Laying the Foundation Top Story Point and Click
A Difficult Choice
After the workout I gave you last time, you're probably either chomping at the bit to build another PHP application or you've decided to give up PHP programming and try growing cucumbers instead. If it's the latter, you should stop reading right now, because I can guarantee you that this concluding installment of PHP 101 has absolutely nothing to teach you about vegetable farming.
If it's the former, however, then you're going to enjoy what's coming up. Over the next few pages, I'm going to be building a simple RSS news aggregator using PHP, SQLite and SimpleXML. With this news aggregator, you can plug into RSS news feeds from all over the web, creating a newscast that reflects your needs and interests for your website. The best part: it updates itself automatically with the latest stories every time you view it!
Come on in, and let's get this show on the road!
Alphabet Soup
I'll start with the basics. What the heck is RSS anyhow?
RSS (the acronym stands for RDF Site Summary) is a format originally devised by Netscape to distribute information about the content on its My.Netscape.Com portal. The format has gone through many iterations since its introduction in early 1997 (take a look at http://backend.userland.com/stories/rss091 for information on RSS's long and complicated history) but most feeds use RSS 1.0 or RSS 0.91, both of which are lightweight yet full-featured.
RSS makes it possible for webmasters to publish and distribute information about what's new and interesting on a particular site at a particular time. This information, which could range from a list of news articles to stock market data or weather forecasts, is published as a well-formed XML document, and can therefore be parsed, processed and rendered by any XML parser - including the SimpleXML parser that is part of PHP 5.
Quite a few popular web sites make an RSS or RDF news feed available to the public at large. Freshmeat and Slashdot both have one, and so do many others, including the PEAR, PECL and Zend sites. A quick Google search for public RSS feeds will get you more links than you can shake a stick at.
An RSS document typically contains a list of resources (URLs), marked up with descriptive metadata. Here's an example:
As you can see, an RDF file is split up into clearly demarcated sections. First comes the document prolog, namespace declarations, and root element. This is followed by a <channel> block, which contains general
information on the channel that is described by this RDF file. In the example above, the channel is Melonfire's Trog column, which gets updated every week with new technical articles and tutorials.
The <channel> block contains an <items> block, which contains a sequential list of all the resources described
within the RDF document. Every resource in this block corresponds to a resource described in greater detail in a subsequent <item> block. Every <item> block describes a single resource in greater detail, providing a title, an
URL and a description of that resource. It's this information that our application will use to generate a personalized news feed.
Laying the Foundation
Now that you know what RSS and RDF are all about, it's time to start work. I'll begin by sitting down at a table near the window and doodling aimlessly on a sheet of paper until I figure out exactly what my application is supposed to do, piece by piece (actually, in this case, the requirements are actually pretty basic):
1. The application must support one or more RSS-compliant news feeds. On start-up, the application should retrieve the latest versions of these feeds, parse them and display their contents in an easy-to-read manner. A SQLite database is a good choice to store this list of feeds.
2. The user should be able to control the number of stories s/he picks up from each feed. For example, a
<?xml version="1.0" encoding="UTF-8"?> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/"> <channel rdf:about="http://www.melonfire.com/"> <title>Trog</title> <description>Well-written technical articles and tutorials on web technologies</description> <link>http://www.melonfire.com/community/columns/trog/</link> <items> <rdf:Seq> <li rdf:resource="http://www.melonfire.com/community/columns/trog/article.php?id=100" /> <li rdf:resource="http://www.melonfire.com/community/columns/trog/article.php?id=71" /> <li rdf:resource="http://www.melonfire.com/community/columns/trog/article.php?id=62" /> </rdf:Seq> </items> </channel> <item rdf:about="http://www.melonfire.com/community/columns/trog/article.php?id=100"> <title>Building A PHP-Based Mail Client (part 1)</title> <link>http://www.melonfire.com/community/columns/trog/article.php?id=100</link> <description>Ever wondered how web-based mail clients work? Find out here.</description> </item> <item rdf:about="http://www.melonfire.com/community/columns/trog/article.php?id=71"> <title>Using PHP With XML (part 1)</title> <link>http://www.melonfire.com/community/columns/trog/article.php?id=71</link> <description>Use PHP's SAX parser to parse XML data and generate HTML pages.</description> </item> <item rdf:about="http://www.melonfire.com/community/columns/trog/article.php?id=62"> <title>Access Granted</title> <link>http://www.melonfire.com/community/columns/trog/article.php?id=62</link> <description>Precisely control access to information with the SQLite grant tables.</description> </item> </rdf:RDF>
Page 1 of 6Zend Developer Zone | PHP 101 (part 15): No News is Good News
user might want to display more science and health news than business news. 3. The application should offer the user a web-based interface to add or delete news feeds. This interface will use PHP's SQLite API to run appropriate SQL queries on the SQLite database file and alter the information stored in the database.
Keeping these requirements in mind, it's possible to design a simple database table to hold the (user-configurable) list of RSS news feeds. Here's what it might look like:
From the table above, it's clear that every news feed will have three attributes: a descriptive title, the URL to the feed itself, and a value indicating how many of the stories in the feed you would like to see displayed in your own custom news page.
Let's add some data to get things started:
You can create all this directly from the schema file rss.sql using the SQLite command .read from the
command-line client, if you still have that on board from Part Nine. In fact, now would be a good time for you to download all the source code for this application, so that you can check it out and refer to it easily throughout this tutorial. Note that you will need a PHP 5-enabled web server to run this code.
Top Story
With the database safely in its web-inaccessible directory, the next step is to write the code that uses the data inside it to connect to each news feed, parse it for news data, and present a customized news page.
Here's what that code, user.php, looks like:
Here's what the output might look like (note that there will a time lag in producing the page, because PHP will be silently opening HTTP connections to each URL to retrieve the corresponding RSS feed):
CREATE TABLE rss ( id INTEGER NOT NULL PRIMARY KEY, title varchar(255) NOT NULL, url varchar(255) NOT NULL, count INTEGER NOT NULL );
INSERT INTO rss VALUES(1, 'Slashdot', 'http://slashdot.org/slashdot.rdf', 5); INSERT INTO rss VALUES(2, 'Wired News', 'http://www.wired.com/news_drop/netcenter/nINSERT INTO rss VALUES(3, 'Business News', 'http://www.npr.org/rss/rss.php?topicId=INSERT INTO rss VALUES(4, 'Health News', 'http://news.bbc.co.uk/rss/newsonline_world_edition/healt
<?php // PHP 5 // include configuration file include('config.php'); // open database file $handle = sqlite_open($db) or die('ERROR: Unable to open database!'); // generate and execute query $query = "SELECT id, title, url, count FROM rss"; $result = sqlite_query($handle, $query) or die("ERROR: $query. ".sqlite_error_string(sqlite_last_error($handle))); // if records present if (sqlite_num_rows($result) > 0) { // iterate through resultset // fetch and parse feed while($row = sqlite_fetch_object($result)) { $xml = simplexml_load_file($row->url); echo "<h4>$row->title</h4>"; // print descriptions for ($x = 0; $x < $row->count; $x++) { // for RSS 0.91 if (isset($xml->channel->item)) { $item = $xml->channel->item[$x]; } // for RSS 1.0 elseif (isset($xml->item)) { $item = $xml->item[$x]; } echo "<a href=\"$item->link\">$item->title</a><br />$item->description<p />"; } echo "<hr />"; // reset variables unset($xml); unset($item); } } // if no records present // display message else { ?> <font size = '-1'>No feeds currently configured</font> <?php } // close connection sqlite_close($handle); ?>
Page 2 of 6Zend Developer Zone | PHP 101 (part 15): No News is Good News
The code to accomplish this might look simple, but there's actually a lot going on behind the scenes. The first step is to obtain a list of the RSS feeds configured by the user from the SQLite database. To accomplish this, a SQLite database handle is initialized, and a SQL SELECT query is executed. A while() loop is used to iterate
through the resulting record collection.
For each URL thus obtained, the simplexml_load_file() function is used to retrieve and read the RSS feed. Depending on the number of stories to be displayed, a for() loop is executed and the appropriate number of <item> elements in the feed are parsed. Notice that the path to access an <item> differs depending on whether the feed is RSS 0.91 or RSS 1.0.
Note that if the database is empty, an error message will appear. In this example, since I've already inserted a bunch of records into the database, you'll never see the error message at all; however, it's good programming practice to ensure that all eventualities are accounted for, even remote ones.
As before, the file config.php is included at the top of every script. This file contains database access parameters, as below:
Point and Click
With the news display out of the way, all that's left is to add a simple administrative tool to manipulate the contents of the SQLite database. The code here is going to be very similar to what you saw in PHP 101 Part 14: a start page called admin.php that provides a snapshot of the current database, and a form to add new entries. Here it is in full:
<?php // database details // always use a directory that cannot be accessed from the web $path = $_SERVER['DOCUMENT_ROOT'].'/../'; $db = $path.'rss.db'; ?>
<html> <head><basefont face = 'Arial'></head> <body> <h2>Feed Manager</h2> <h4>Current Feeds:</h4> <table border = '0' cellspacing = '10'> <?php // PHP 5 // include configuration file include('config.php'); // open database file $handle = sqlite_open($db) or die('ERROR: Unable to open database!'); // generate and execute query $query = "SELECT id, title, url, count FROM rss"; $result = sqlite_query($handle, $query) or die("ERROR: $query. ".sqlite_error_string(sqlite_last_error($handle))); // if records present if (sqlite_num_rows($result) > 0) { // iterate through result set // print article titles while ($row = sqlite_fetch_object($result)) {
Page 3 of 6Zend Developer Zone | PHP 101 (part 15): No News is Good News
As you can see, there are two sections in this script. The first half connects to the database and prints a list of all the currently configured news feeds, with a "delete" link next to each. The second half contains a form for the administrator to add a new feed, together with its attributes.
Once the form is submitted, the data gets POST-ed to the script add.php, which validates it and saves it to the
database. Here's the code for add.php:
?> <tr> <td><?php echo $row->title; ?> (<?php echo $row->count; ?>)</td> <td><font size = '-2'><a href="delete.php?id=<?php echo $row->id; ?>">delete</a></font></td> </tr> <?php } } // if there are no records present, display message else { ?> <font size = '-1'>No feeds currently configured</font> <?php } // close connection sqlite_close($handle); ?> </table> <h4>Add New Feed:</h4> <form action = 'add.php' method = 'post'> <table border = '0' cellspacing = '5'> <tr> <td>Title</td> <td><input type = 'text' name = 'title'></td> </tr> <tr> <td>Feed URL</td> <td><input type = 'text' name = 'url'></td> </tr> <tr> <td>Stories to display</td> <td><input type = 'text' name = 'count' size = '2'></td> </tr> <tr> <td colspan = '2' align = 'right'><input type = 'submit' name = 'submit' value = 'Add RSS Feed'></td> </tr> </table> </form> </body>
</html>
<html>
Page 4 of 6Zend Developer Zone | PHP 101 (part 15): No News is Good News
The lower half of the script should be familiar to you: it contains the usual function calls to open an SQLite database and execute an INSERT query to save the user's data to the database. What's interesting, though, is
the top half of the script, which contains a number of input tests to ensure that the data being saved doesn't contain gibberish.
There are three tests here. One checks for the presence of a descriptive title, another uses the is_numeric() function to verify that the value entered for the story count is a valid number, and the third uses the ereg()
function to check the format of the URL. If you read Part 13, you'll know all about the importance of validating user input; here's that theory going into action.
That takes care of adding new RSS feeds. Now, what about removing them?
Remember how, in admin.php, each feed displayed in the list had a "delete" link, which pointed to the script delete.php. This delete.php script takes care of deleting a news feed from the table, given the feed ID (which is passed through the link). Take a look at the code, and things will become clearer:
<head><basefont face = 'Arial'></head> <body> <h2>Feed Manager</h2> <?php // PHP 5 if (isset($_POST['submit'])) { // check form input for errors // check title if (trim($_POST['title']) == '') { die('ERROR: Please enter a title'); } // check URL if ((trim($_POST['url']) == '') || !ereg("^http\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\._\?\,\'/\\\+&%\$#\=~\-])*$", $_POST['url'])) { die('ERROR: Please enter a valid URL'); } // check story number if (!is_numeric($_POST['count'])) { die('ERROR: Please enter a valid story count'); } // include configuration file include('config.php'); // open database file $handle = sqlite_open($db) or die('ERROR: Unable to open database!'); // generate and execute query $query = "INSERT INTO rss (title, url, count) VALUES ('".$_POST['title']."', '".$_POST['url']."', '".$_POST['count']."')"; $result = sqlite_query($handle, $query) or die("ERROR: $query. ".sqlite_error_string(sqlite_last_error($handle))); // close connection sqlite_close($handle); // print success message echo "Item successfully added to the database! Click <a href = 'admin.php'>here</a> to return to the main page"; } else { die('ERROR: Data not correctly submitted'); } ?> </body>
</html>
<html> <head><basefont face = 'Arial'></head> <body> <h2>Feed Manager</h2> <?php // PHP 5 if (isset($_GET['id']) && is_numeric($_GET['id'])) { // include configuration file include('config.php'); // open database file $handle = sqlite_open($db) or die('ERROR: Unable to open database!'); // generate and execute query $query = "DELETE FROM rss WHERE id = '".$_GET['id']."'"; $result = sqlite_query($handle, $query) or die("ERROR: $query. ".sqlite_error_string(sqlite_last_error($handle))); // close connection sqlite_close($handle); // print success message echo "Item successfully removed from the database! Click <a href = 'admin.php'>here</a> to return to the main page"; } else { die('ERROR: Data not correctly submitted');
Page 5 of 6Zend Developer Zone | PHP 101 (part 15): No News is Good News
The record ID passed through the URL GET method is retrieved by delete.php, and used with a DELETE SQL query to erase the corresponding record. Try it out and see for yourself!
And that's about all I have for you. I hope you enjoyed the 15-part journey that was PHP 101, and that you found it both educational and fun - I know I did, and it was a pleasure having you along for the ride. If you'd like to read more about specific aspects of PHP, drop by www.melonfire.com and take a look at some more of my tutorials and articles. Until then... happy coding!