Monday, 21 January 2013

Programming and Problem Solving in PHP #2

Hey guys,

Time for tutorial #2 in my series of Programming and Problem Solving posts! Today the first thing we're going to do is go over some things that weren't touched on in detail in the last tutorial that you should be familiar with before we proceed.

The first thing to notice is that in the last tutorial the code had a lot of semi-colons ";" this is a symbol used by the interpreter to determine where the end of each command is. Generally speaking(although there are exceptions which we will touch on) every line should end with a semi-colon, you can also stack two commands onto a single line like this:

<?php
echo "Hello"; echo " "; echo "Dickwad\n";
?>

If anyone was expecting that last echo to say world, im sorry to disapoint but thats just a little toooooo cliche. the previous segment of code, to the interpreter, is identical to:

<?php
echo "Hello";
echo " ";
echo "Dickwad\n";
?>

and

<?php
echo "Hello Dickwad\n";
?>

note that although you CAN stack commands onto one line, unless you have a specific reason to you should avoid doing such, even though it will execute fine on the computer end, if you or anyone else has to actually maintain the code it can make things a lot more painful.

Another convention that Im going to do everything I can to drill into you guys is proper indentation. I dont give 2 fucks if you think you can obfuscate your code by leaving it unindented and sloppy, trust me a half retarted monkey could reverse just about any of the obfuscation ive seen in skiddy php shells and scripts, all it serves to do is make you look like you dont know what the fuck you're doing and like you don't belong anywhere near a modern computer. When you have a script of hundreds, thousands, or even millions of lines of code that you have to maintain and manage, INDENTATION IS KEY. say it again because its that important. INDENTATION IS KEY. Until we touch on conditional statements later in this tutorial I won't be able to give much of a concrete example so this is all ill say on indentation for now.

You may have noticed in the code examples that they always begin with <?php and end with ?>, these tags tell the php interpreter what to process(since you can splice php code among html you can have a script entirely in html with a single <?php include 'menu.php'; ?> inside the html, so these tags exist to tell the interpreter exactly what to process and what to ignore.) There is short tags available as well which let you use simply <? and ?>, this is a setting that needs to be changed in the php.ini configuration file, but regardless, <?php ?> should work no matter what.

One more thing to catch up on before we dig any deeper. PHP is a recursive acronym, it stands for PHP Hypertext Preprocessor. The key word we're looking for here is pre-processor. If any of you have written in C or C++ you may be familiar with the concept of a preprocessor, its what takes all the #include files(like #include <iostream> and #include "stdlib.h") and embeds those libraries into your current file. PHP also has this feature available so you can include libraries and scripts into new applications you write(this may seem like a somewhat complicated concept at the moment but trust me its pretty simple and makes scripts way more reuseable) with this in mind we have 4 ways of including external scripts into our main script

For more information on Preprocessors: http://en.wikipedia....ki/Preprocessor

include()
include_once()
require()
require_once()

as you can see they're all quite similar ill start first with the differences between include and require

basically if you require a file and its unavailable, the program will stop execution and throw you an error saying that you're a real jerkface telling it to look for files that don't exist. If you use include it will continue execution and proceed but without the code that you intended to include so it very well may break down if any of that code is directly referenced or you may end up with a website that only half renders, etc... but the key difference between require and include is that with require if its not there its not loading.

now to touch on require_once and include_once, they both have the same differences that require and include have. the _once indicates that if in your script you have several references to a file and require or include it in more than one spot, to reduce overhead it will check and only actually load that file into memory once and use that location for all future references, instead of loading the same library into memory multiple times.

That being said, I almost exclusively use require_once, it ensures that overhead is limited and that my script won't errenously proceed without its requirements. However you should assess each situation and determine which is the most appropriate for your specific needs.

OK so we're caught up and I think we're ready to move onto something new. For once we'll get into some real actual coding... This next part is going to be broken into two parts, as PHP is primarily used in two ways: as a web application scripting language and as a command line scripting language. So we'll run through a few examples of how to obtain user input through both the command line as well as through using html forms on a web page.

We'll start off by doing it using the command line which may seem a little bit more complicated but by and large is a lot less work than creating a web page to read the info and send it off to be processed.

<?php

$input;
print "Enter your name: ";
$input = trim(fgets(STDIN));
print "Your name is: " . $input . "\n";

?>

so what we've done here is created a variable named $input, we then prompt the user to enter their name(notice the print "Enter your name: " doesn't have the \n character in it. This means that when the user enters text it will appear directly to the right of the prompt instead of the line below it) Then we come to the line: $input = trim(fgets(STDIN)); in this line we are assigning the result of trim(fgets(STDIN)) to the variable $input. trim() is a function used to remove whitespace and endline characters as well as a few others. The reason for this is if they enter "Harold" and hit enter, the value of input will be "Harold\n" so if you print $input it will jump a line, trim removes the \n and leaves us with just the data we want. fgets(STDIN) extracts the data from the standard input buffer(in this case whatever was typed on the keyboard) Thats it, this is really all you need to know to get started with command line scripts and user input.

Obtaining input from a web form takes a few more lines of code so i'll write out an example first then well go through it piece by piece.

[code]
<?php
if(isset($_GET['sentinel']))
{
        print "Your name is: " . $_GET['name'] . "\n";
}
else
{
?>
<form method="GET" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="text" id="name" name="name" placeholder="Enter your name..." />
<input type="hidden" id="sentinel" name="sentinel" value="1" />
<input type="submit" value="Submit" />
</form>
<?php
}
?>


NOTE**: the line of an if statement does NOT require a semi-colon, just if(condition){} each line within the {} requires a semi-colon but the if statement itself does not.

Theres a few things in this code that we haven't taken a look at yet so I'll give a brief overview here but we'll go more into detail on them later.

We see here says: if(isset($_GET['sentinel']))

What we're really telling the computer is that if the variable $_GET['sentinel'] exists then we want to execute the following indented block of code, in this case a single print statement. If that variable does not exist we want to skip that line and instead execute the other block of indented code which presents an html form to the user asking for their name. This is what we refer to as a control structure, the concept of if/else clauses allows us to create several alternative courses of action that will be executed depending on which conditions are met, in this case the condition is the existence of the $_GET['sentinel'] variable. We call these kinds of operations "Conditionals" or "Conditional Statements". Why do we care if $_GET['sentinel'] exists? lets take a closer look at the second block of code

<form method="GET" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="text" id="name" name="name" placeholder="Enter your name..." />
<input type="hidden" id="sentinel" name="sentinel" value="1" />
<input type="submit" value="Submit" />
</form>

if you're familiar with html most of this should be pretty straight forward, by using the GET method we're basically saying "Send these variables in the clear via the URL" and you'll notice when you submit the form the URL changes to something like: http://192.168.1.146...rian&sentinel=1
Trailing from the URL are the values: name=Brian&sentinel=1 notice in the Form we have two input fields name and sentinel that correspond with these, so when the form is submitted two variables are being created: $_GET['sentinel'] and $_GET['name'] if these don't exist we can safely assume the user has not submitted the form, therefore we want to display the form to get them to fill it out. However if these variables do exist we can reasonable assume they have filled out the form and instead want to display the results back to them. Technically there are 3 input types, the submit is one as well but fuck submit thats irrelevant.

If you want to submit form data but have it not appear in the URL(say someones logging into a website, sending the username and password clearly in the URL is obviously a bad idea)  then you can use the POST method instead of GET, all you have to do is substitute method="GET" for method="POST" and prefix your variables with $_GET instead of $_POST. This is also an example of a self-contained script. We wrote the input and processing stages all to one file. But what if we need to send the data from a form to a different file? the action="" determines where to send the request, we have sent it to $_SERVER['PHP_SELF'] which is a variable that contains the name of the file we're using so basically it says "send it back to me, ill reload and re-evaluate" but you can instead put in any file name you like.

So now we've got an introduction into some basic user input, as well as conditional statements. But conditionals, as we've seen them thusfar, seem kind of limited don't they? right now we can only choose between two options, if this do this otherwise do that. For some problems this will be sufficient but its not hard to see this being insufficient for more complex problems. So lets look at the If/Else claus a little more thoroughly and look into a concept known as nesting.

Nesting is the concept of inserting one block of code into another block of code, for example the form in the previous example was nested under the else statement and the print was nested under the if statement. Lets write a simple script to determine if its morning or afternoon, as well as if its a weekday or if its the weekend:


<?php
$day = date("l");//returns the full name of the current day e.g.: Monday, Friday
$timeday = date("a");//returns either am or pm in lower case

if($day == "Saturday" || $day == "Sunday")
{
        print "It's the weekend!\n";
        if($timeday == "am")
                print "\t It's the morning!\n";
        else
                 print "\t It's the Afternoon!\n";
}
else
{
        print "It's a weekday :(\n";
        if($timeday == "am")
                 print "\t It's the morning!\n";
        else
                 print "\t It's the Afternoon!\n";
}

?>

Alright so a few things we can ignore here are basically the date() function, it's beyond the scope of this tutorial but I've included in the comments exactly what data is being sent to those variables to give you an idea of what its doing.

In this code we have an if else block embedded inside of the if else block, this way we can create even more potential flows of execution. A few other things that we havn't seen before are || and == we'll discuss || and some other corresponding operators later on but for now lets focus on ==. Remember in the previous tutorial when I said to make a note of one = sign meaning assignment? e.g. $var1 = 5; assigns the value of 5 to $var1, when we use two equal signs its to compare the values of two items, so:

if($day == "Saturday" || $day == "Sunday")

is checking to see if $day is equal to the value Saturday or if $day is equal to the value Sunday(|| is the logical or operator, if $day is equal to either of those values, the condition returns true and the block of code is executed, only if each condition is wrong will it continue on to the else) so basically the first thing we're checking is if its a weekend or a weekday, then outputting those results, from there we check if its morning or afternoon then output that as well. You might notice that the outer blocks use {} brackets to contain their blocks whereas the internal if/else statements don't. This is a matter of preference but to break things down:

if there is ONE and only ONE line of code, you may omit the brackets(still be sure to indent so that its readily apparant, if you dont indent it will still run perfectly fine but could be a bit boggling to read) if there is more than one line of code you MUST i repeat MUST use {} brackets to contain it. Heres why:

say you have 3 or 4 conditions you want to check but only have an if/else and nothing to say this or this or this or this(note i dont mean this || this || this i mean if this else if this else if this else this)

we can write it such as:

if(condition 1)
        process 1
else
        if(condition 2)
                process 2
        else
                if(condition 3)
                        process 3
                else
                        process 4

this might take a second to set in, and understandably so but basically this lets us check through a number of options, it is however written in a overly complex way, so people have constructed the concept of the else if statement written this way for clarity:

if(condition 1)
        process 1
else if(condition 2)
        process 2
else if(condition 3)
        process 3
else
        process 4

THIS IS the correct way to write it. using if/else if/else statements we can effectively check through any combination of conditions that we need(well not exactly but with the help of || and some other operators we can achieve that goal)

Apart from if/else statements theres another option for running through conditionals, its used less often but excels in certain situations so for the sake of a full background we'll go over the switch statement next:

the format of a switch statement is to take a variable then check its value against a number of options, if any are true then a block of code is executed, lets look a little closer:

switch($variable)
{
        case "Sunday":
                print "Sunday\n";
                break;
        case "Monday":
                print "Monday\n";
                break;
        case "Tuesday":
                print "Tuesday\n";
                break;
        case "Wednesday":
                print "Wednesday\n";
                break;
        case "Thursday":
                print "Thursday\n";
                break;
        case "Friday":
                print "Friday\n";
                break;
        case "Saturday":
                print "Saturday\n";
                break;
}


in this example we're reviewing the value of $variable, if it corresponds to any of the days of the week that day will be printed, so when we see case "" what lies between the "" is what we are comparing it to, you can also use case 0: case 1: case 2: etc... if you're using a numerical value(it can be useful when iterating through an array, more on that later!)
notice the break statement at the end of each block too, break tells the program to break outside of the current block(basically it looks for the next } character and executes the line after it) if we don't include break after every case it will continue executing the code from each following case, so if we remove break from sunday and $variable == "Sunday" then we will have sunday and monday print out. Knowing this we can actually create teh equivalent of || statements by omitting break statements:


switch($variable)
{
        case "Saturday":
        case "Sunday":
                print "Weekend!\n";
                break;
        case "Monday":
        case "Tuesday":
        case "Wednesday":
        case "Thursday":
        case "Friday":
                print "Weekday :(\n";
                break;
}


So now if the day is a sat or sun it will print weekend otherwise it will print weekday, pretty cool huh?

Alright so you guys have been patient and we've been taking in a lot of fairly boring info without getting down and dirty and writing any real code so nows your reward! the following are a few case studies, I'll help by presenting you with an algorithm and leave it to you to write up these programs and test them on your own. If anyone has any difficulty or questions don't hesitate to shoot me a pm or post a reply and ask and ill be glad to help as quickly as I possibly can! All of these except for the last can be done in command line or in a web application, its up to you which you'd prefer to work in or if you're a hardcore you can do it in both :) the last is specific to web pages(alternating background colours for table rows!)


Case Study 1:

    Modify the earlier script that prompts the user for a name, have it prompt them for a name and an age and print out both results back to them

    Algorithm:
        prompt user for username
        prompt user for age
        print results back to user

Case Study 2:

    Change Sorter
    A script to prompt the user for the amount of change they have(in cents) the script then performs some basic calculations on the data to determine the number of dollars, quarters, dimes, nickels, and pennies in the change

    Algorithm:
        prompt user for amount of change
        divide change by 1.00 to get the number of dollars
        modulus divide change by 1.00 to get remaining change
        divide remaining change by .25 to get the number of quarters
        modulus divide the remaining change by .25 to get the remaining change
        divide the remaining change by .10 to get thenumber of dimes
        modulus divide the remaining change by .10 to get the remaining change
        divide the remaining change by .05 to get the number of quarters
        modulus divide the remaining change by .05 to get the number of pennies
        print the results to the user

Case Study 3:
  
    Basic Calculator
    Create a calculator that allows the user to enter two numerical values as well as an operator to perform a mathematical calculation and output the results

    Algorithm:
        prompt user for first number
        prompt user for second number
        prompt user for operator(+-/*%)
        perform calculation and output results

Case Study 4:

    Alternating Row Colours
    often when generating html tables we want to stylize them to have alternating background colours, you can do this manually but its tedious and laborious, using modulus division we can create an infinite on-off sequence, imagine we have each row keyed to a value 0-9 well say if the row key % 2 is equal to 0 then make it colour a otherwise make it colour B


    key:
    0        %2 == 0
    1        %2 == 1
    2        %2 == 0
    3        %2 == 1
    4        %2 == 0
    5        %2 == 1
    6        %2 == 0
    7        %2 == 1
    8        %2 == 0
    9        %2 == 1

No comments:

Post a Comment