WickedCoolPHP
byWilliamSteinmetz;BrianWard
Publisher:NoStarch
PubDate:February9,2008
PrintISBN-13:978-1-593-27173-2
Pages:216
TableofContents|Index
Overview
PHPisaneasy-to-usescriptinglanguageperfectforquickly
creatingtheWebfeaturesyouneed.Onceyouknowthebasics
ofhowthelanguageworks,wouldn'titbegreattohavea
collectionofusefulscriptsthatsolvethosetrickyproblemsand
addinterestingfunctionalitytoyoursite?Wethoughtso,too.
Insteadofstartingat"HelloWorld,"WickedCoolPHPassumes
thatyou'refamiliarwiththelanguageandjumpsrightintothe
goodstuff.AfteryoulearntheFAQsoflife-themostcommonly
wishedforPHPscripts-you'llworkyourwaythroughsmart
configurationoptionsandtheartofforms,allthewaythrough
tocomplexdatabase-backedscripts.
WickedCoolPHPcontainsawidevarietyofscriptstoprocess
creditcards,checkthevalidityofemailaddresses,template
HTML,andservedynamicimagesandtext.The76easily
implementedscriptswillalsoteachyouhowto:
Sendandreceiveemailnotifications
Trackyourvisitors'behaviorwithcookiesandsessions
OverridePHP'sdefaultsettings
Manipulatedates,images,andtextonthefly
HarnessSOAPandotherwebservices
Createanonlinepoll,ecarddeliverysystem,andblog
Butit'snotallfunandgames:Securityisabigconcernwhen
programminganywebapplication.Soyou'lllearnhowto
encryptyourconfidentialdata,safeguardyourpasswords,and
preventcommoncross-site-scriptingattacks.Andyou'lllearn
howtocustomizeallofthescriptstofityourownneeds.
DynamicWebcontentdoesn'thavetobedifficult.Learnthe
secretsofthecraftfromtwoexperiencedPHPdeveloperswith
WickedCoolPHP.
WickedCoolPHP
byWilliamSteinmetz;BrianWard
Publisher:NoStarch
PubDate:February9,2008
PrintISBN-13:978-1-593-27173-2
Pages:216
TableofContents|Index
WICKEDCOOLPHP.
INTRODUCTION
Chapter1.THEFAQSOFLIFE—THESCRIPTSEVERYPHP
PROGRAMMERWANTS(ORNEEDS)TOKNOW
Section1.1.#1:IncludingAnotherFileasaPartofYour
Script
Section1.2.#2:HighlightingAlternateRowColorsinaTable
Section1.3.#3:CreatingPrevious/NextLinks
Section1.4.#4:PrintingtheContentsofanArray
Section1.5.#5:TurninganArrayintoaNonarrayVariable
ThatCanBeRestoredLater
Section1.6.#6:SortingMultidimensionalArrays
Section1.7.#7:TemplatingYourSitewithSmarty
Chapter2.CONFIGURINGPHP
Section2.1.ConfigurationSettingsandthephp.iniFile
Section2.2.#8:RevealingAllofPHP'sSettings
Section2.3.#9:ReadinganIndividualSetting
Section2.4.#10:ErrorReporting
Section2.5.#11:SuppressingAllErrorMessages
Section2.6.#12:ExtendingtheRunTimeofaScript
Section2.7.#13:PreventingUsersfromUploadingLarge
Files
Section2.8.#14:TurningOffRegisteredGlobalVariables
Section2.9.#15:EnablingMagicQuotes
Section2.10.#16:RestrictingtheFilesthatPHPCanAccess
Section2.11.#17:ShuttingDownSpecificFunctions
Section2.12.#18:AddingExtensionstoPHP
Chapter3.PHPSECURITY
Section3.1.RecommendedSecurityConfigurationOptions
Section3.2.#19:SQLInjectionAttacks
Section3.3.#20:PreventingBasicXSSAttacks
Section3.4.#21:UsingSafeHTML
Section3.5.#22:ProtectingDatawithaOne-WayHash
Section3.6.#23:EncryptingDatawithMcrypt
Section3.7.#24:GeneratingRandomPasswords
Chapter4.WORKINGWITHFORMS
Section4.1.SecurityMeasures:FormsAreNotTrustworthy
Section4.2.VerificationStrategies
Section4.3.Using$_POST,$_GET,$_REQUEST,and
$_FILEStoAccessFormData
Section4.4.#25:FetchingFormVariablesConsistentlyand
Safely
Section4.5.#26:TrimmingExcessWhitespace
Section4.6.#27:ImportingFormVariablesintoanArray
Section4.7.#28:MakingSureaResponseIsOneofaSet
ofGivenValues
Section4.8.#29:UsingMultipleSubmitButtons
Section4.9.#30:ValidatingaCreditCard
Section4.10.#31:Double-CheckingaCreditCard's
ExpirationDate
Section4.11.#32:CheckingValidEmailAddresses
Section4.12.#33:CheckingAmericanPhoneNumbers
Chapter5.WORKINGWITHTEXTANDHTML
Section5.1.#34:ExtractingPartofaString
Section5.2.#35:MakingaStringUppercase,Lowercase,or
Capitalized
Section5.3.#36:FindingSubstrings
Section5.4.#37:ReplacingSubstrings
Section5.5.#38:FindingandFixingMisspelledWordswith
pspell
Section5.6.#39:RegularExpressions
Section5.7.#40:RearrangingaTable
Section5.8.#41:CreatingaScreenScraper
Section5.9.#42:ConvertingPlaintextintoHTML-Ready
Markup
Section5.10.#43:AutomaticallyHyperlinkingURLs
Section5.11.#44:StrippingHTMLTagsfromStrings
Chapter6.WORKINGWITHDATES
Section6.1.HowUnixTimeWorks
Section6.2.#45:GettingtheCurrentTimestamp
Section6.3.#46:GettingtheTimestampofaDateinthe
PastorFuture
Section6.4.#47:FormattingDatesandTimes
Section6.5.#48:CalculatingtheDayoftheWeekfroma
GivenDate
Section6.6.#49:FindingtheDifferenceBetweenTwoDates
Section6.7.MySQLDateFormats
Chapter7.WORKINGWITHFILES
Section7.1.FilePermissions
Section7.2.#50:PlacingaFile'sContentsintoaVariable
Section7.3.#51:CreatingandWritingtoaFile
Section7.4.#52:CheckingtoSeeIfaFileExists
Section7.5.#53:DeletingFiles
Section7.6.#54:UploadingImagestoaDirectory
Section7.7.#55:ReadingaComma-SeparatedFile
Chapter8.USERANDSESSIONTRACKING
Section8.1.UsingCookiesandSessionstoTrackUserData
Section8.2.#56:Creatinga"WelcomeBack,Username!"
MessagewithCookies
Section8.3.#57:UsingSessionstoTemporarilyStoreData
Section8.4.#58:CheckingtoSeeIfaUser'sBrowser
AcceptsCookies
Section8.5.#59:RedirectingUserstoDifferentPages
Section8.6.#60:ForcingaUsertoUseSSL-Encrypted
Pages
Section8.7.#61:ExtractingClientInformation
Section8.8.#62:SessionTimeouts
Section8.9.#63:ASimpleLoginSystem
Chapter9.WORKINGWITHEMAIL
Section9.1.#64:UsingPHPMailertoSendMail
Section9.2.#65:UsingEmailtoVerifyUserAccounts
Chapter10.WORKINGWITHIMAGES
Section10.1.#66:CreatingaCAPTCHA(Security)Image
Section10.2.#67:CreatingThumbnailImages
Chapter11.USINGcURLTOINTERACTWITHWEBSERVICES
Section11.1.#68:ConnectingtoOtherWebsites
Section11.2.#69:UsingCookies
Section11.3.#70:TransformingXMLintoaUsableForm
Section11.4.#71:UsingMappingWebServices
Section11.5.#72:UsingPHPandSOAPtoRequestData
fromAmazon.com
Section11.6.#73:BuildingaWebService
Chapter12.INTERMEDIATEPROJECTS
Section12.1.#74:AUserPoll
Section12.2.#75:ElectronicGreetingCards
Section12.3.#76:ABloggingSystem
AppendixA.APPENDIX
COLOPHON
Index
WICKEDCOOLPHP.
Copyright©2008byWilliamSteinmetzwithBrianWard.
Allrightsreserved.Nopartofthisworkmaybereproducedor
transmittedinanyformorbyanymeans,electronicor
mechanical,includingphotocopying,recording,orbyany
informationstorageorretrievalsystem,withouttheprior
writtenpermissionofthecopyrightownerandthepublisher.
PrintedonrecycledpaperintheUnitedStatesofAmerica
1211100908
123456789
ISBN-10:1-59327-173-5
ISBN-13:978-1-59327-173-2
Publisher:
WilliamPollock
ProductionEditor:
MeganDunchak
CoverandInteriorDesign:
OctopodStudios
DevelopmentalEditor:
TylerOrtman
TechnicalReviewer:
ScottGilbertson
Copyeditor:
LindaRecktenwald
Compositor:
RileyHoffman
Proofreader:
JeanneHansen
Indexer:
KarinArrigoni
Forinformationonbookdistributorsortranslations,please
contactNoStarchPress,Inc.directly:
NoStarchPress,Inc.
555DeHaroStreet,Suite250,SanFrancisco,CA94107
phone:415.863.9900;fax:415.863.9950;
;www.nostarch.com
LibraryofCongressCataloging-in-PublicationData
CodeView:
Steinmetz,William.
WickedcoolPHP:real-worldscriptsthatsolvedifficultpro
andBrian
Ward.--1sted.
p.cm.
Includesindex.
ISBN-13:978-1-59327-173-2
ISBN-10:1-59327-173-5
1.PHP(Computerprogramlanguage)I.Ward,Brian,1972-II.T
QA76.73.P224S742008
005.13'3--dc22
2005
NoStarchPressandtheNoStarchPresslogoareregistered
trademarksofNoStarchPress,Inc.Otherproductandcompany
namesmentionedhereinmaybethetrademarksoftheir
respectiveowners.Ratherthanuseatrademarksymbolwith
everyoccurrenceofatrademarkedname,weareusingthe
namesonlyinaneditorialfashionandtothebenefitofthe
trademarkowner,withnointentionofinfringementofthe
trademark.
Theinformationinthisbookisdistributedonan"AsIs"basis,
withoutwarranty.Whileeveryprecautionhasbeentakeninthe
preparationofthiswork,neithertheauthornorNoStarch
Press,Inc.shallhaveanyliabilitytoanypersonorentitywith
respecttoanylossordamagecausedorallegedtobecaused
directlyorindirectlybytheinformationcontainedinit.
INTRODUCTION
ThisbookisforthedeveloperwhohasstumbledontoPHPand
wantstoknowhowtogetthingsdone.Youshouldknowthe
basicsofprogramming,andchancesareyou'veseenmany
onlinecodesamples.Butyoumaybewonderingwhysome
examplesaremuchmorecomplicatedthanotherswhentheydo
thesamething.
Carehasbeentakentokeeptheexamplesinthisbookas
simpleaspossibleandtoexplainasmuchaspossibleabout
everypieceofcode.Tokeepclientandservercodeconfusionto
aminimum,thereisn'tmuchJavaScripthere.Everyone's
impatient,soChapter1,"TheFAQsofLife—TheScriptsEvery
PHPProgrammerWants(orNeeds)toKnow,"containsquick
solutionstoeveryone'sfavoritelittletasksandproblems.After
youcalmdown,takealookatChapter2,"ConfiguringPHP,"to
findouthowyoushouldinstallandconfigurePHP—quitealarge
numberofproblemsarisefrommisconfiguration.Continuingin
thisvein,Chapter3,"PHPSecurity,"dealswithkeepingyour
scriptssecure.
Chapter4,"WorkingwithForms,"returnstobasics—specifically,
howtogetuserinputfromformsandotherdynamicinput
sources.Chapter5,"WorkingwithTextandHTML,"showshow
toprocesstextandstringswithanumberoftools,including
regularexpressions.Chapter6,"WorkingwithDates,"discusses
howtoworkwithtimesanddatesinPHPandMySQL,and
Chapter7,"WorkingwithFiles,"dealswithfilemanipulation.
Withthesefundamentalscovered,Chapter8,"UserandSession
Tracking,"coversthedetailsofsessiontrackingand
management.Withmultipleusersonacomplexwebsite,it's
importanttokeeptrackofwhateachuserisdoingsothatone
user'ssessiondoesn'tinterferewithanother's.
Chapter9,"WorkingwithEmail,"andChapter10,"Working
withImages,"coveremailandimagemanipulation,
respectively.Thesetasksareoftenill-suitedforwebserver
scripts,sothechaptersdescriberelativelylightweighttasksthat
canaddsignificantvaluetoyoursite.
InChapter11,"UsingcURLtoInteractwithWebServices,"
you'lllearnhowtomakeyourserverinteractwithwebservices
onothersitesviaXML.
Finally,Chapter12,"IntermediateProjects,"containsthreefun
littleprojectsthatcanbeincorporatedintolargerwebsites.
Theseprojectsbuildonwhatyou'velearnedelsewhereinthe
book.
Chapter1.THEFAQSOFLIFE—THE
SCRIPTSEVERYPHPPROGRAMMER
WANTS(ORNEEDS)TOKNOW
Thescriptscontainedinthischapteranswerseveralquestions
thatclogPHPforumsanddiscussiongroupsallovertheworld.
Theyincludethefollowing:
HowdoIaddPrevious/Nextlinkstomyshoppingcart?
Isthereaneasywaytomakeeveryotherrowinmytablea
differentcolor?
IhaveabigarraythatIneedtosort—help!
What'sthebesttemplatingsystemtomakethesameHTML
enclosemydataoneverypage?
Althoughtherearemorecomplicatedscriptslaterinthisbook,
andmanyothersthatyoumayfindmorevaluable,thesescripts
answerthequestionsthatIseeagainandagain.Theonlything
thesebeginningscriptshaveincommonisthatthey—reeither
thethingsthateveryoneshouldknoworthethingsthat
everyonewantstoknow.HandthischaptertoabeginningPHP
programmeryoulove.She—llthankyouforit.
Note:Ifyou'renotafraidtostartrootingaroundonyour
webserver,Chapter2willalsohelpthebeginningPHPscripter
andcanmakelifealoteasierforthemidlevelPHPprogrammer.
Youmightwanttogotherenext.
1.1.#1:IncludingAnotherFileasaPart
ofYourScript
Mostseriousapplicationshaveacorelibraryofvariablesand
scriptsthatareusedonalmosteverypage.Forexample,if
you'rewritingashoppingcartthatconnectstoaMySQL
database,youcoulddeclaretheMySQLloginnameand
passwordoneachpageofyourcart.Butwhatifyouneedto
changethepassword?Changinganduploadingeveryfilein
yourshoppingcartcouldbecomeahugeissue.
Ratherthandeclaringthepasswordineachofyourpage
scripts,youcanstorethatnameandpasswordinaseparate
file.Youcanthenincludethatfileasapartofyourscript,and
whatevervariablesyoudeclareinthatfilewillbedeclaredin
yourscript!
Furthermore,youcanstorelongscriptsorfunctionsina
separatefileandincludethemonlywhenyouneedthem.For
example,thefunctionthatgetsreal-timeUPSshippingquotes
is24KBworthofXMLprocessinggoodness,butyouuseitonly
whensomeonechoosesUPSasashippingoption.Whynot
storeitinups_ship_quotes.phpandcallitonlywhen
necessary?
Infact,almostallheavy-dutyPHPapplicationshaveafilecalled
somethinglikeconfig.php,whichdeclaresthecriticalvariables
thateverypageneedstoknow,suchastheMySQLnameand
password.Thosesameapplicationsalsostorefrequentlyused
scriptsindifferentdirectories.Programmersthenmixand
match,takingthecheck-to-see-if-a-user-is-logged-inscript
fromonedirectory,includingtheget-the-relevant-data-fromthe-databasescriptfromanotherdirectory,andwritingacentral
scriptthatscreensthedatabasedonwhethertheuseris
loggedinornot.
Andhere'showtodoit.
require_once("/path/to/file.php");
?>
Thefilethatyougivetorequire_once()isnowapartofyour
script,exactlyasifyouhadcutandcopiedthecontentsofthe
fileintoyourscript.YoucanevenincludeHTMLfilestocreatea
crudetemplatingsystem.
Nomatterwhatyounamethefile,PHPtriestoreaditasifit
werevalidPHP.AswithanyPHPfile,youneedthe>markersaroundthePHPcodeinyourincludedfile;otherwise,
PHPsimplyprintstheentirefile(evenifit'sabinary).
Youcanuserequire_once()justlikeanyotherstatement,so
feelfreetoembeditintocontrolstructures.
if($we_need_this_file===true){
require_once("needed_file.php");
}
1.1.1.WhatCanGoWrong?
Severalthingscangoawrywhenyou'reincludingafile.
Thepathtothescriptiswrong.
Ifthishappens,thescriptreturnsafatalerroranddies.If
you'dliketoensurethatthescriptwillrunevenifitcan't
findanincludefile,useinclude_once()insteadof
require_once().
Thepathtothescriptiscorrect,butthescriptisina
forbiddendirectory.
Thiscanhappenifyou'veconfiguredtheopen_basedir
settingtorestrictthedirectoriesthatPHPcanaccess.Web
developersrestrictaccesstoimportantfilesanddirectories
forsecuritypurposes.We'llshowyouhowtochange
directorypermissionsin"#16:RestrictingtheFilesthatPHP
CanAccess"onSection2.9.
Theincludefilehasablanklineorspacebeforeorafter
thecodeinthePHPscript.
Ifyourscriptsetscookiesordoesanythingelsetocreatea
nonstandardHTTP,itmustdosobeforesendinganyoutput
tothebrowser.Remember,PHPprintsanythingoutsideof
its<?phpand?>markersinanincludefile.Therefore,if
youhaveablanklinebeforeorafterthesemarkers,that
linewillbesenttothebrowserjustasifitwasplainHTML,
andonceHTMLissenttothebrowser,cookiescannotbeset
andsessionscannotbestarted.Ifyou'reincludingascript,
makesureithasnowhitespaceoutsidethePHPtags.Be
especiallycarefulofspacesafterthe?>endmarker,
becauseyounormallycan'tseethemwhenediting.
Note:Cookiesareusedfortrackingusersandstoring
hiddeninformation.SeeChapter8formoredetails.
Theincludefilecanbeviewedbynon-PHPmethods.
YoucanstorePHPvariablesinanyfileregardlessofits
filename,butifyoudon'tspecificallyconfigureApacheto
makethosefilesunreadable,Apachecanservethemupas
plaintexttoanyonewhoasks.Therefore,anyonewho
knowsthenamesofyourincludefilescanreadeverything
inthemifyou'renotcareful.
Needlesstosay,storingyourMySQLpasswordsandmaster
accountnamesinaplacewhereanyonewithInternet
Explorercanseethemisnotconsideredgoodsecurity
practice.
Totightensecurity,youcanplaceincludefilesoutsidethe
webdirectories(preferablyinapassword-protected
directory)sopeoplecanaccessthescriptonlythroughFTP.
Infact,ifyou'redealingwithsensitiveinformationsuchas
creditcardauthorizationdata,youshouldfeelobligatedto
doso.
Note:We'llseehowtovalidateacreditcardnumberin
"#30:ValidatingaCreditCard"onSection4.8.
You'reinincludeoverload.
Ioncepurchasedashoppingcartprogrambecauseitwas
writteninPHP,andIplannedtocustomizethescriptstofit
mybusiness.ImaginemysurprisewhenIfoundoutthat
thecentralmoduleofthecart'sscript(wherepeopleadded,
deleted,andadjusteditems)consistedof7includes,12
linesofactualcode,and3Smartytemplates.Iopenedone
oftheincludedfiles,anditwas—youguessedit—aseriesof
threeadditionalincludes.
Includescanmakeyourcodeverycompact.Buttakeit
fromme:Ifyou'retryingtodecipherhowahyper-included
scriptworks,it'salivinghell.Forthesakeofother
programmersandfuturegenerations,pleasedon'tincludea
filewithoutacommentthattellspeoplewhatthatincluded
filedoes.Thankyou.
You'reusinguncheckedvariablesasincludefilenames.
Althoughyoucandosomethinglikeinclude($file)to
openthecorrectscriptdependingonwhatauserchooses,
doingsomayallowahackertoincludeanyfileinthesite
withabitoftweakingor,dependingonyourserversettings,
afileonhissite,whichthenbreaksintoyourserver.Infact,
acoupleofPHP-basedwormsrelyonbadlywrittenscripts
likethis.Moreover,thesetypesofscriptsarefarmoreprone
tostrangebugsandaregenerallyimpossibletoread.
Ifyoumustincludearangeoffileswithavariable,usea
scriptliketheoneshownin"#28:MakingSureaResponse
IsOneofaSetofGivenValues"onSection4.7.1toverify
thatthefilenamesarepermissible,whichpreventssomeone
fromopeningyourrootpasswordfile.
Chapter1.THEFAQSOFLIFE—THE
SCRIPTSEVERYPHPPROGRAMMER
WANTS(ORNEEDS)TOKNOW
Thescriptscontainedinthischapteranswerseveralquestions
thatclogPHPforumsanddiscussiongroupsallovertheworld.
Theyincludethefollowing:
HowdoIaddPrevious/Nextlinkstomyshoppingcart?
Isthereaneasywaytomakeeveryotherrowinmytablea
differentcolor?
IhaveabigarraythatIneedtosort—help!
What'sthebesttemplatingsystemtomakethesameHTML
enclosemydataoneverypage?
Althoughtherearemorecomplicatedscriptslaterinthisbook,
andmanyothersthatyoumayfindmorevaluable,thesescripts
answerthequestionsthatIseeagainandagain.Theonlything
thesebeginningscriptshaveincommonisthatthey—reeither
thethingsthateveryoneshouldknoworthethingsthat
everyonewantstoknow.HandthischaptertoabeginningPHP
programmeryoulove.She—llthankyouforit.
Note:Ifyou'renotafraidtostartrootingaroundonyour
webserver,Chapter2willalsohelpthebeginningPHPscripter
andcanmakelifealoteasierforthemidlevelPHPprogrammer.
Youmightwanttogotherenext.
1.1.#1:IncludingAnotherFileasaPart
ofYourScript
Mostseriousapplicationshaveacorelibraryofvariablesand
scriptsthatareusedonalmosteverypage.Forexample,if
you'rewritingashoppingcartthatconnectstoaMySQL
database,youcoulddeclaretheMySQLloginnameand
passwordoneachpageofyourcart.Butwhatifyouneedto
changethepassword?Changinganduploadingeveryfilein
yourshoppingcartcouldbecomeahugeissue.
Ratherthandeclaringthepasswordineachofyourpage
scripts,youcanstorethatnameandpasswordinaseparate
file.Youcanthenincludethatfileasapartofyourscript,and
whatevervariablesyoudeclareinthatfilewillbedeclaredin
yourscript!
Furthermore,youcanstorelongscriptsorfunctionsina
separatefileandincludethemonlywhenyouneedthem.For
example,thefunctionthatgetsreal-timeUPSshippingquotes
is24KBworthofXMLprocessinggoodness,butyouuseitonly
whensomeonechoosesUPSasashippingoption.Whynot
storeitinups_ship_quotes.phpandcallitonlywhen
necessary?
Infact,almostallheavy-dutyPHPapplicationshaveafilecalled
somethinglikeconfig.php,whichdeclaresthecriticalvariables
thateverypageneedstoknow,suchastheMySQLnameand
password.Thosesameapplicationsalsostorefrequentlyused
scriptsindifferentdirectories.Programmersthenmixand
match,takingthecheck-to-see-if-a-user-is-logged-inscript
fromonedirectory,includingtheget-the-relevant-data-fromthe-databasescriptfromanotherdirectory,andwritingacentral
scriptthatscreensthedatabasedonwhethertheuseris
loggedinornot.
Andhere'showtodoit.
require_once("/path/to/file.php");
?>
Thefilethatyougivetorequire_once()isnowapartofyour
script,exactlyasifyouhadcutandcopiedthecontentsofthe
fileintoyourscript.YoucanevenincludeHTMLfilestocreatea
crudetemplatingsystem.
Nomatterwhatyounamethefile,PHPtriestoreaditasifit
werevalidPHP.AswithanyPHPfile,youneedthe>markersaroundthePHPcodeinyourincludedfile;otherwise,
PHPsimplyprintstheentirefile(evenifit'sabinary).
Youcanuserequire_once()justlikeanyotherstatement,so
feelfreetoembeditintocontrolstructures.
if($we_need_this_file===true){
require_once("needed_file.php");
}
1.1.1.WhatCanGoWrong?
Severalthingscangoawrywhenyou'reincludingafile.
Thepathtothescriptiswrong.
Ifthishappens,thescriptreturnsafatalerroranddies.If
you'dliketoensurethatthescriptwillrunevenifitcan't
findanincludefile,useinclude_once()insteadof
require_once().
Thepathtothescriptiscorrect,butthescriptisina
forbiddendirectory.
Thiscanhappenifyou'veconfiguredtheopen_basedir
settingtorestrictthedirectoriesthatPHPcanaccess.Web
developersrestrictaccesstoimportantfilesanddirectories
forsecuritypurposes.We'llshowyouhowtochange
directorypermissionsin"#16:RestrictingtheFilesthatPHP
CanAccess"onSection2.9.
Theincludefilehasablanklineorspacebeforeorafter
thecodeinthePHPscript.
Ifyourscriptsetscookiesordoesanythingelsetocreatea
nonstandardHTTP,itmustdosobeforesendinganyoutput
tothebrowser.Remember,PHPprintsanythingoutsideof
its<?phpand?>markersinanincludefile.Therefore,if
youhaveablanklinebeforeorafterthesemarkers,that
linewillbesenttothebrowserjustasifitwasplainHTML,
andonceHTMLissenttothebrowser,cookiescannotbeset
andsessionscannotbestarted.Ifyou'reincludingascript,
makesureithasnowhitespaceoutsidethePHPtags.Be
especiallycarefulofspacesafterthe?>endmarker,
becauseyounormallycan'tseethemwhenediting.
Note:Cookiesareusedfortrackingusersandstoring
hiddeninformation.SeeChapter8formoredetails.
Theincludefilecanbeviewedbynon-PHPmethods.
YoucanstorePHPvariablesinanyfileregardlessofits
filename,butifyoudon'tspecificallyconfigureApacheto
makethosefilesunreadable,Apachecanservethemupas
plaintexttoanyonewhoasks.Therefore,anyonewho
knowsthenamesofyourincludefilescanreadeverything
inthemifyou'renotcareful.
Needlesstosay,storingyourMySQLpasswordsandmaster
accountnamesinaplacewhereanyonewithInternet
Explorercanseethemisnotconsideredgoodsecurity
practice.
Totightensecurity,youcanplaceincludefilesoutsidethe
webdirectories(preferablyinapassword-protected
directory)sopeoplecanaccessthescriptonlythroughFTP.
Infact,ifyou'redealingwithsensitiveinformationsuchas
creditcardauthorizationdata,youshouldfeelobligatedto
doso.
Note:We'llseehowtovalidateacreditcardnumberin
"#30:ValidatingaCreditCard"onSection4.8.
You'reinincludeoverload.
Ioncepurchasedashoppingcartprogrambecauseitwas
writteninPHP,andIplannedtocustomizethescriptstofit
mybusiness.ImaginemysurprisewhenIfoundoutthat
thecentralmoduleofthecart'sscript(wherepeopleadded,
deleted,andadjusteditems)consistedof7includes,12
linesofactualcode,and3Smartytemplates.Iopenedone
oftheincludedfiles,anditwas—youguessedit—aseriesof
threeadditionalincludes.
Includescanmakeyourcodeverycompact.Buttakeit
fromme:Ifyou'retryingtodecipherhowahyper-included
scriptworks,it'salivinghell.Forthesakeofother
programmersandfuturegenerations,pleasedon'tincludea
filewithoutacommentthattellspeoplewhatthatincluded
filedoes.Thankyou.
You'reusinguncheckedvariablesasincludefilenames.
Althoughyoucandosomethinglikeinclude($file)to
openthecorrectscriptdependingonwhatauserchooses,
doingsomayallowahackertoincludeanyfileinthesite
withabitoftweakingor,dependingonyourserversettings,
afileonhissite,whichthenbreaksintoyourserver.Infact,
acoupleofPHP-basedwormsrelyonbadlywrittenscripts
likethis.Moreover,thesetypesofscriptsarefarmoreprone
tostrangebugsandaregenerallyimpossibletoread.
Ifyoumustincludearangeoffileswithavariable,usea
scriptliketheoneshownin"#28:MakingSureaResponse
IsOneofaSetofGivenValues"onSection4.7.1toverify
thatthefilenamesarepermissible,whichpreventssomeone
fromopeningyourrootpasswordfile.
1.2.#2:HighlightingAlternateRow
ColorsinaTable
Whenyouhavelotsofinformationpresentedinrows,suchas
topicsinaforumorlineitemsinashoppingcart,individual
rowsaremucheasiertoreadwheneveryotherrowisaslightly
differentcolor.Thefirststepistodefinecolorsfortablerowsin
yourstylesheet.
tr.row1{
background-color:gray;
}
tr.row2{
background-color:white;
}
Therearetwostyleclassesherefortablerowtags(<tr>),
row1androw2.AswithanyCSS,youcanplacethisinsidea
preexistingCSSfilethatyourdocumentincludesorencloseit
within<style></style>tagsinyourdocumenthead.
Nowlet'sdefineafunctionthatalternatelyreturnsthese
classes.There'salittletrickhere—youpassanintegervariable
tothisfunctionbyreference.Thefunctionautomatically
updatesthisvariablesothatyoucanmakerepeatedcalls
withoutworryingaboutthecurrentstateofthetable:
functiontable_row_format(&$row_counter){
//Returnsrowclassforarow
if($row_counter&1){
$row_color="row2";
}else{
$row_color="row1";
}
$row_counter++;
return$row_color;
}
Nowlet'sseehowtousethisfunction.First,let'ssetupanSQL
querytosomerowsofdatafromthetabledescribedinthe
AppendixAandstartthetableformatting:
$sql="SELECTproduct_nameFROMproduct_info";
$result=@mysql_query($sql,$db)ordie;
echo"<table>";
Therestiseasy;wejustneedtoinitializetherowstatevariable
(here,$i),repeatedlycalltable_row_format($i)togetthe
alternatingrowstyleclasses,andthengiveeachrowthe
correctclassattribute.Finally,weclosethetable:
$i=0;
while($row=mysql_fetch_array($result)){
/*Printresults.*/
$row_class=table_row_format($i);
echo"<trclass=\"$row_class\"><td>$row[product_name]</td><
}
echo"</table>";
Thekeytousingthetable_row_format()functionis
understandinghowitworks.Youalwaysinitializeaninteger
variableforthestate,butitdoesn'tmatterwhatthevalueis,
becausetable_row_format()takescareofitforyou.
1.2.1.HackingtheScript
Thereareamillioncheaptricksyoucandowiththestylesheet.
FormoredetailsonCSS,consulttheonlineresourceofyour
choice,ortakealookatCascadingStyleSheets:TheDefinitive
Guide,2ndEdition,byEricMeyer(O'ReillyMedia,2004).
Perhapsmoreinterestingly,youcaneasilyconvertthisfunction