More PHP - PowerPoint PPT Presentation

1 / 59
About This Presentation
Title:

More PHP

Description:

name = 'car' /textarea /p p input type='submit' value='Submit' align='middle' / /p ... mail ( string to, string subject, string message) ... – PowerPoint PPT presentation

Number of Views:97
Avg rating:3.0/5.0
Slides: 60
Provided by: Bil150
Category:
Tags: php | more

less

Transcript and Presenter's Notes

Title: More PHP


1
More PHP
2
What we'll cover
  • A short history of php
  • Parsing
  • Variables
  • Arrays
  • Operators
  • Control Structures
  • Forms
  • Functions
  • Accessing the shell
  • Sockets
  • Regular Expressions

3
Forms
  • Obviously, one of the things you need to handle
    are forms
  • You can make an html only form, and submit that
    to a php file
  • You can also make a single php file that makes
    the form, and submit that to itself, and on the
    submit, present a different page, and then after
    a confirmation present a third page, and so on,
    and so on.
  • We'll talk about both

4
Simple Form
ltform action"./simpleform.php" method"GET"
name"choices"gt ltpgtWhat is the meaning of
life?lt/pgt ltpgtlttextarea rows"1" cols"50"
wrap"virtual" name "answer"gtlt/textareagt
lt/pgt ltpgtWhat is your name?lt/pgt ltpgtlttextarea
rows"1" cols"50" wrap"virtual" name
"name"gtlt/textareagtlt/pgt ltpgtWhere is your
car?lt/pgt ltpgtlttextarea rows"1" cols"50"
wrap"virtual" name "car"gtlt/textareagtlt/p
gt ltpgtltinput type"submit" value"Submit"
align"middle" /gtlt/pgt lt/formgt
simpleform/simpleform.html
5
Simple Form php
lt?php if (count(_GET) lt 1) echo "no
GETs!" else echo "Here is the GET
array" echo "ltpregt" print_r(_GET)
echo "lt/pregt" ?gt
  • The php that catches the form reads the GET array
  • All this one does is used print_r() to show the
    results
  • Can you think of any advantages or disadvantages
    to using two separate pages this way?
  • What about the first condition? When is it met?

simpleform/simpleform.php
6
Simple form to itself
  • To do all of this with one php file, we need a
    way to detect where we are in the process
  • So on first load, we present the form
  • On second load, after submitting the form, we
    process results

7
simpleform_self.php
lt?php if (!_GET) echo "ltform
action\"" . _SERVER"PHP_SELF" . "\"
method\"GET\" name\"choices\"gt\n"
echo "ltpgtWhat is the meaning of life?lt/pgt
ltpgtlttextarea rows\"1\" cols\"50\"
wrap\"virtual\" name
\"answer\"gtlt/textareagtlt/pgt\n" echo "ltpgtWhat
is your name?lt/pgt ltpgtlttextarea rows\"1\"
cols\"50\" wrap\"virtual\" name
\"name\"gtlt/textareagtlt/pgt\n" echo "ltpgtWhere
is your car?lt/pgt ltpgtlttextarea rows\"1\"
cols\"50\" wrap\"virtual\" name
\"car\"gtlt/textareagtlt/pgt\n" echo 'ltinput
type"hidden" value "111" name "key_number"
/gt' echo 'ltpgtltinput type"submit"
value"Submit" align"middle" /gtlt/pgt'
8
simpleform_self.php
else echo "Here is the GET array"
echo "ltpregt" print_r(_GET) echo
"lt/pregt" ?gt lt/formgt lt/bodygt lt/htmlgt
  • When the form is submitted, the url has a GET
    array
  • So it passes past the if statement, and lands on
    the else, where we process data
  • Again, we're just print_r()'ing the results
  • There's an error here, can you spot it?

9
Sessions
  • A very useful aspect to php is the ability to
    maintain session data
  • To do this, you create a session, then load it
    with data
  • The session data is stored server side, usually
    in /etc, and is keyed (but not encrypted), and
    remains for that url and remote ip

10
simpleform_self_session.php
  • Sessions need to be created before any html
    headers are sent, so do this at the very top of
    the page
  • Use session_register() to create slots for
    variables
  • After these variables are populated, you can
    access them via the _SESSION array
  • In this example we'll define a key (randomly
    generated) and a counter (to track steps)

11
simpleform_self_session.php
lt?php // Start a session, and set a key and a
counter // A session is a method of tracking
state for a given // browser session, and allows
storage of data on the server session_start() //
create a session session_register('session_key')
// register a session var for a key to

// track this session
// this is done to
help detect reloads session_register('session_coun
ter') // session counter is used to
//
track where we are in
// a session ?gt
12
simpleform_self_session.php
  • Now, we can check see if the key is set, if not,
    we're on a first load and we generate a key and
    set the counter to 0.

// if the session_key is not yet set, generate a
random number for the key // and set the
session_counter to 0 (this situation indicates
that the form // is being loaded for the first
time) if (!_SESSION'session_key')
_SESSION'session_key' rand()
_SESSION'counter' 0
13
simpleform_self_session.php
  • Then we build the form--note the use of PHP_SELF,
    and the hidden input.

// If we don't have key_number, then the user
hasn't filled in the form if (!_GET"key_number"
) echo "ltform action\"" .
_SERVER"PHP_SELF" . "\" method\"GET\"
name\"choices\"gt\n" echo "ltpgtWhat is the
meaning of life?lt/pgtltpgtlttextarea rows\"1\"
cols\"50\" wrap\"virtual\" name
\"answer\"gtlt/textareagtlt/pgt\n"
echo 'ltinput type"hidden" value "' .
_SESSION'session_key' . '" name
"key_number" /gt' echo 'lt/formgt'
_SESSION'counter' 1
14
simpleform_self_session.php
  • Next, we have an elseif that looks to see that we
    have the data we need and that there's a key and
    that counter is set to one
  • Then we start by printing the results.

elseif (_SESSION'session_key'
_GET"key_number" _SESSION'counter' 1
(_GET"answer" _GET"name"
_GET"car")) echo "Here is the GET
array" echo "ltpregt" print_r(_GET)
echo "lt/pregt"
15
simpleform_self_session.php
  • and then we make a confirmation form and set
    the counter to 2
  • And again we submit the form to itself

echo "ltform action\"" . _SERVER"PHP_SELF" .
"\" method\"GET\" name\"choices\"gt\n" echo
'ltinput type"hidden" value "' .
_SESSION'session_key' . '" name
"key_number" /gt' echo 'ltpgtAre these ok?lt/pgt'
echo 'ltinput type"radio" value"yes" name
"yes_no" /gtyes ltinput type"radio"
value"no" name "yes_no" /gtno' echo 'ltpgtltinput
type"submit" value"Submit" align"middle"
/gtlt/pgt' echo 'lt/formgt'
_SESSION'counter' 2
16
simpleform_self_session.php
  • Next, we check for the confirmation and kill the
    session, if things are good here, we do good
    things..

// Check again that the session_key matches the
key_number, and that we're on step number three,
and for "yes" elseif (_SESSION'session_key'
_GET"key_number" _SESSION'counter' 2
_GET"yes_no" "yes") echo
'ltpgtCool, everything\'s copacetic.lt/pgt' //
Here you'd do the Good Thing, whatever that is.
// Destroy the session session_unset()
session_destroy()
17
simpleform_self_session.php
  • And we check for badness.

// Check again that the session_key matches the
key_number, and that we're on step number three,
and for "no" elseif (_SESSION'session_key'
_GET"key_number" _SESSION'counter' 2
_GET"yes_no" "no") echo
'ltpgtOops, sorry, lta href"./simpleform_self_sessio
n.php"gt try again?lt/agtlt/pgt' // Here
you'd do the Bad Thing, whatever that is
// Destroy the session session_unset()
session_destroy()
18
simpleform_self_session.php
  • And a final sanity check
  • This is not particularly clean, since we're not
    checking much, and esp. because this is where we
    land if not all fields are filled in--better ways
    to deal with this?

// If no conditions matched, assume something
went wrong and try to cope else echo
'ltpgtI\'m sorry, I found a problem, perhaps you
didn\'t fill in all of the boxes. lta
href"./simpleform_self_session.php"gt
Continue?lt/agtlt/pgt' // Destroy the session
session_unset() session_destroy()
19
User Defined Functions
  • Like javascript, php supports user defined
    functions
  • Declare your functions towards the top of your
    php file--this is not a requirement, just good
    practice
  • Functions are created when the program is read,
    and before execution
  • Or, build an exterior file with commonly used
    functions, and give that a version number. Then
    require that file to reuse your code (see the
    general functions file in the samples for
    examples I use)

20
Passing Data
  • The simplest way to pass data into a function is
    through that functions argument list of variable
    (and arrays are a type of variable)// wrap the
    variable in pfunction echo_p(wrapped_item)
    echo "ltpgtwrapped_itemlt/pgt"
  • You can also set default values, but watch
    placement--defaults to the right please// wrap
    the variable in h// default to level 2function
    echo_h(wrapped_item, level"2") echo "lth"
    . level . "gtwrapped_itemlt/h" . level. "gt\n"

12
21
Scope
  • Functions themselves have global scope--functions
    defined within functions are available everywhere
  • Variables assigned or modified inside of a
    function have their value only within the
    function
  • A variable can be declared global within a
    function, however, if you want to pass that
    variable into and out of the function
  • Generally, it's better to leave variable scope
    limited, this makes the function portable.

15
22
Functions have Global Scope
  • Unlike variables, functions are global in scope
  • But a function doesn't execute until called
  • Here, foo() is used to create bar()
  • Once foo() is called, bar() exists
  • bar() is available outside of foo()

function foo() function bar() echo
"I don't exist until foo() is called.\n"
/ We can't call bar() yes since it
doesn't exist. / foo() / Now we can call
bar(), foo()'s processing has made it
accessible. / bar() ?gt
this example is 17.3 from the php manual, up as
14_functions.php See also 15_function_scope.php
23
Functions and Default Values
function good_echo_h(wrapped_item, level"2")
echo "lth" . level . "gtwrapped_itemlt/h"
. level. "gt\n" function bad_echo_h(level"
2", wrapped_item) echo "lth" . level .
"gtwrapped_itemlt/h" . level. "gt\n"
good_echo_h("A good heading") good_echo_h("A
good heading at level 1", 1) bad_echo_h(2, "A
bad heading with level set") bad_echo_h("A bad
heading with no level set")
  • Defaults must occur to the right

12_function_defaults.php
24
An Example Building an FAQ
  • Core program calls 5 functions, 3 local and 2
    external
  • 1 Data file and some variables
  • This kind of program structure makes
    understanding a large program much easier

25
aform
  • This is set up in samples and the labs section,
    both, so you can do the lab to figure this out
  • Based on a general survey form I came up with a
    few years ago

26
aform
  • Uses the general_functions file
  • Data is external in a text file
  • The code that makes the various types of question
    in the form is also external
  • By keeping data and question types separate, it's
    easy to use the same program to make different
    surveys

27
Leveraging the Shell
28
Back tick and shell_exec()
  • Php uses backticks (olde school) and the function
    shell_exec() to process shell commands (usually
    through bash)
  • Shell commands execute with the environment and
    rights of the web server
  • Opening a shell is not lightweight in terms of
    ram, so keep in mind it can be expensive
  • Very useful if a wheel already exists in your
    setup (Netcheck is an example).

04
29
10_show_source.php
  • I wanted to be able to display source code for
    the php programs
  • There is a function, highlight_file(), that will
    handle syntax highlighting for a php file
  • I could have written the whole thing in php (and
    that could be a portfolio project), but I already
    had this file listing shell script.
  • This wheel already exists
  • If the server supports it, files ending in .phps
    will show highlighted source (this is an apache
    directive)
  • See also http//www.sitepoint.com/article/highligh
    t-source-code-php

30
Sockets
31
Theory of Sockets
  • A socket is a combination of an ip number, a
    protocol and a port
  • Servers listen on a socket, clients will open a
    connection to that socket
  • What gets sent back and forth over the socket
    connection varies with the protocol
  • Generally, when working with a client, you don't
    specify the local socket you'll use (the os
    handles that), just the remote socket

32
An example Web Request
fp fsockopen("www.cs.unc.edu", 80,
errno, errstr, 30) if (!fp) echo
"errstr (errno)ltbr /gt\n" else out
"GET /index.html HTTP/1.1\r\n" out .
"Host www.example.com\r\n" out .
"Connection Close\r\n\r\n" fwrite(fp,
out) while (!feof(fp)) echo
fgets(fp, 128) fclose(fp)
  • This is a socket call to a web server
  • fp represents a "handle" to the socket
  • If the handle is created, you have the socket

11_webconnection.php
33
Sending email with PHP
  • The unix version of PHP includes support for
    sendmailmail ( string to, string subject,
    string message)
  • Since windows doesn't support sendmail, the
    windows build of PHP uses an external smtp
    server, but uses the same command
  • But it doesn't work under OSX by default--OS X
    uses postfix, and that's off by default
  • I could have enabled postfix, but I'm a geek...

34
Example Protocol SMTP
  • By convention, smtp servers listen on ports 25
    and 587
  • By the rfc, smtp servers communicate in plain
    text--you can telnet to an smtp server to send
    email
  • Verbs in smtp include helo, mail from, rcpt to,
    data
  • Use "." to end the body of a message (and this
    is one place where a potential for hacking
    exists)

35
An SMTP call
gilgamesh hays telnet smtp.unc.edu 25 Trying
152.2.1.140... Connected to smtp.unc.edu. Escape
character is ''. 220 smtp.unc.edu ESMTP
UNC-Chapel Hill - ITS Email Tue, 30 Sep 2008
185657 -0400 (EDT) helo gilgamesh 250
smtp.unc.edu Hello gilgamesh.cs.unc.edu
152.2.131.71, pleased to meet you mail
fromhays_at_cs.unc.edu 250 2.1.0 hays_at_cs.unc.edu...
Sender ok rcpt tob_at_unc.edu 250 2.1.5
b_at_unc.edu... Recipient ok data 354 Enter mail,
end with "." on a line by itself Subject
Test To b_at_unc.edu From hays_at_cs.unc.edu Howdy,
this is a test. . 250 2.0.0 m8UMuvtq021026
Message accepted for delivery quit 221 2.0.0
smtp.unc.edu closing connection Connection closed
by foreign host.
36
Bits and pieces
  • fsockopen opens a connection, and establishes a
    point to that connection, with server, port and
    timeout specifiable
  • fwrite (or fputs) and fgets write and read to
    that connection, feof tests for end of file

fp fsockopen("www.example.com", 80, errno,
errstr, 30) if (!fp) echo "errstr
(errno)ltbr /gt\n" else out "GET /
HTTP/1.1\r\n" out . "Host
www.example.com\r\n" out . "Connection
Close\r\n\r\n" fwrite(fp, out) while
(!feof(fp)) echo fgets(fp, 128)
fclose(fp) this from php manual
16
37
My version of mail
  • I didn't want to enable a mail server, so I
    hacked an emailer function that
  • Checks the message for some possible hacks
  • Checks the MX record of the target domain
  • Opens a connection to an smtp server
  • Writes the message to that connection
  • Checks the responses for success or failure

38
The call
  • Call this function with a message id, an array
    that contains the tos, a subject line, the
    message, the ip of the web server, the smtp
    server to use, and the portemailer(rand(10000,
    30000), to_list, "hays_at_cs.unc.edu", "Test",
    "test test test", _SERVER"REMOTE_ADDR",
    "smtp.unc.edu", "587")

39
Sanity Checks
  • Check for the to list to be an array (coercion
    can occur)
  • Check for embedded addresses and periods

if (!is_array(email_to))
die('Sorry, email_to must be an array')
email_subject str_replace("."," .
",email_subject) email_text
str_replace("."," . ",email_text)
email_subject str_replace("_at_"," AT
",email_subject) email_text
str_replace("_at_"," AT ",email_text)
40
Check Email Validity
  • list(username,domain) split("_at_",email_from
    )
  • if (!getmxrr(domain,mxrecords))
  • echo "ltpgtError The email domain for the
    \"from\" address, email_from, cannot be
    verified.lt/pgt"
  • echo "ltpgtMail sent from this address may
    not be deliverable, and replies may not
    work!lt/pgt"
  • // end of if
  • y0
  • while (email_toy !'')
  • list(username,domain)
    split("_at_",email_toy)
  • if (!getmxrr(domain,mxrecords))
  • echo "ltpgtError The email domain for the
    \"to\" address, email_toy cannot be
    verified.lt/pgt"
  • echo "ltpgtMail sent to this address may
    not be deliverable!lt/pgt"
  • // end of if
  • y
  • // end of while

41
Build Messages
  • This part builds an array, message, that contains
    elements representing each line of the mail
    connection we need
  • We'll walk this array later to send the mail

x0 // Build a helo message, using
the php server's IP name messagex
"HELO " . php_server . "\r\n" x
// Set the from address messagex "MAIL
FROMlt" . email_from . "gt\r\n" x
42
Now the from and tos
  • y0
  • messagex "RCPT TOlt" . email_toy .
    "gt\r\n"
  • to_list email_toy
  • x
  • // Now do a loop to set the rest of the
    recipients.
  • // Pull each address out of the array email_to
    array
  • // and also add that address to the to_list
    for inclusion in the headers
  • y
  • while (email_toy ! '')
  • messagex "RCPT TOlt" . email_toy
    . "gt\r\n"
  • to_list to_list . ", lt" .
    email_toy . "gt"
  • x
  • y
  • // end of while

43
Start a Data Statement
  • Start the data statement // Set the Data
    statement messagex "DATA\r\n" x
  • But the rest of the data statement is messy, it
    contains all of the header data you get in an
    email message--take a deep breath.

44
Email Headers
  • Message-ID lt11819_at_152.2.131.71gt
  • Date Thu, 13 Sep 2007 162051 -0400
  • From hays_at_cs.unc.edu
  • To hays_at_cs.unc.edu
  • Subject Test
  • Content-Type text/plain charsetus-ascii
  • Content-Transfer-Encoding 7bit
  • X-Mailer Php program running from
    wwwx.cs.unc.edu/hays/INLS668/samples/php/function
    s/test.php
  • X-SAV-Scan-By smf-sav v1.4.1 -
    http//smfs.sf.net/
  • Received-SAV Pass (fafnir.cs.unc.edu sender
    hays_at_cs.unc.edu
  • passed Sender Address Verification Test
  • receiverfafnir.cs.unc.edu client-ip152.2.1.139
  • envelope-fromlthays_at_cs.unc.edugt
    helosmtp.unc.edu
  • X-Scanned-By MIMEDefang 2.62 on 152.2.129.97
  • X-Scanned-By MIMEDefang 2.62 on 152.2.129.90

45
Making Email Headers
  • messagex "Message-ID lt" .
    email_messageid . "_at_" . php_server .
    "gt\r\nDate " . date(r) . "\r\nFrom " .
    email_from . "\r\nTo " . to_list .
    "\r\nSubject " . email_subject .
    "\r\nContent-Type text/plain charsetus-ascii\r\
    nContent-Transfer-Encoding 7bit\r\nX-Mailer Php
    program running from ". _SERVER"SERVER_NAME" .
    _SERVER"SCRIPT_NAME" . "\r\n" . email_text .
    "\r\n.\r\n"
  • x
  • // Build a quit message, this is the last step
    when it comes to the connection
  • messagex "QUIT\r\n"

46
Making the Connection
  • stream fsockopen(smtp_server, smtp_port,
    errno, errstr, 30)
  • // Check for error messages from the socket
    connection.
  • if (!stream)
  • echo "ltpgtI'm sorry, there appears to be a
    problem sending email. \n"
  • echo 'ltpgtPlease report this error. lta
    href"mailto' . email_admin .
    '"gt' . email_admin . "lt/agtlt/pgt\n"
  • echo "ltpgtAlso, this error does not mean
    that anything else went wrong, it
    only indicates \n"
  • echo "that the email message this program
    was trying to send did not go out
    successfully. \n"
  • echo "Anything else you were trying to do
    likely was not affected by
  • this error.lt/pgt\n"
  • // end of if

47
Peel off the data
  • else // Since we got a socket, send the mail
  • x0 // reset x for the loop
  • while (messagex ! '')
  • smtp_response fgets(stream, 1024)
    // Check for server responses
  • sleep(1)
  • fputs(stream, messagex) // Put the
    message line up to the server

48
Check the Server Responses
  • if (substr(smtp_response, 0, 1) gt '3')
  • echo "ltpgtI'm sorry, there appears to
    be a problem sending email. \n"
  • echo "The particular message I
    received waslt/pgt\n"
  • echo "ltpregt" . smtp_response .
    "lt/pregt"
  • // Since there has been a
    nontransient error, try to reset and quit
    gracefully
  • fputs(stream, "RSET")
  • sleep(1)
  • fputs(stream, "QUIT")
  • sleep(1)
  • // Set the next message to null
  • // Since email failed we just give up
    and this exits the loop for us
  • message(x 1) ''
  • //end of if

49
See it in action
  • This is in the functions folder
  • There are earlier versions for comparison (why
    upgrade, and what to what for?)

50
Regular Expressions
51
Simple regular expression
// Check for malodorous site calls if
(ereg("(//)", _GETname)) //echo "Call to
an external site" email_messageid
date(U) email_to0 "hays_at_cs.unc.edu"
email_subject 'Intrusion Attempt from
frame.php' email_text 'There has been an
intrusion attempt originating from '
. HTTP_SERVER_VARSREMOTE_ADDR email_from
"hays_at_cs.unc.edu" php_server
HTTP_SERVER_VARSHTTP_HOST smtp_server
"smtp.cs.unc.edu" smtp_port "25"
emailer(email_messageid, email_to, email_from,
email_subject, email_text,
php_server, smtp_server,
smtp_port)
52
Regular Expressions Syntax
  • Two major dialects, posix and perl (we're using
    the former)
  • The basic usage is "match a_string a_blob", where
    the string is what you're looking for and the
    blob is where it might be
  • There are a lot of variants that do search and
    replace, forward and back, etc., but the basic
    function in PHP is ereg()

53
ereg() examples
  • ereg("fair", blob) looks for the string "fair"
  • ereg(0-9, blob) looks for any instance of a
    digit from 0 to 9
  • ereg(cq, blob) looks for either a c or q (this
    is the same as "cq"
  • ereg((0-3)(fair), blob) looks for any digit
    0-3 or the string "fair" (the is an or)

54
ereg and Anchors
  • ereg((This), blob) looks for This at the
    beginning of blob
  • ereg((This), blob) looks for This at the end of
    blob

55
More examples
  • ereg(7-9.ing, blob) looks for a 7-9 digit,
    following by any single character, followed by
    the string "ing" (the period is a wildcard)
  • ereg(rx4,7, blob) looks for an r followed by
    4-7 x's (the brackets provide the range on the
    prior character
  • ereg(0-95s, blob) looks for 5 digits each in
    the range of 0-9, followed by an s

15_ereg.php
56
Escaping ereg Characters
  • .()?\ are special characters for regular
    expressions, and must be escaped with a backslash
  • ereg(\_at__at__at_\, blob) looks for '_at__at__at_'
  • ereg(",\.\_at__at_, blob) looks for '",._at__at_'

57
For the masochistic Some examples of validation
  • http//www.ilovejackdaniels.com/php/email-address-
    validation/
  • http//www.zend.com/codex.php?id371single1
  • http//scripts.franciscocharrua.com/verify-email-a
    ddress.php

58
Regex info
  • http//www.tin.org/bin/man.cgi?section7topicreg
    ex
  • http//analyser.oli.tudelft.nl/regex/index.html.en
  • http//weblogtoolscollection.com/regex/regex.php

59
Sources
  • http//www.zend.com/zend/art/intro.php
  • http//www.php.net/
  • http//hotwired.lycos.com/webmonkey/programming/ph
    p/index.html
Write a Comment
User Comments (0)
About PowerShow.com