homepage Welcome to WebmasterWorld Guest from 23.22.173.58
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

    
Good PHP solutions to small problems
or PHP Bag of Tricks 2004
jatar_k




msg:1300707
 8:01 pm on Oct 26, 2004 (gmt 0)

I was working on something that called for switching colours recently and I was bored with the old ones I had lying around. I made a new one that is much quicker and actually allows the counter to increment continuously. I sometimes was running double counters and it was a pain, I also didn't like having those extra conditional statements in the bottom of my scripts.

It is only set for 2 options though. I threw it in a little test loop here.

// set your 2 colours
$colour0 = '#336699';
$colour1 = '#ffaa00';
$counter = 0;

while ($counter < 10) {
echo "<br><font color='" . ${'colour' . ($counter % 2)} . "'>this colour</font>";
$counter++;
}

have I ever mentioned how much I love variable variables? ;)

This is just one example of small little snippets I have lying around for various functionality, anyone want to share?

for those of you who haven't seen these they are worth a good read
PHP Bag of Tricks I [webmasterworld.com]
PHP Bag of Tricks II [webmasterworld.com]
PHP Bag of Tricks III [webmasterworld.com]

[edited by: jatar_k at 10:18 pm (utc) on Oct. 26, 2004]

 

coopster




msg:1300708
 10:06 pm on Oct 26, 2004 (gmt 0)

Ever wonder what superglobals [php.net] are available on your system?

<?php 
error_reporting(0); // in case some of the superglobals aren't defined
$superglobals = array(
'$GLOBALS' => $GLOBALS,
'$_SERVER' => $_SERVER,
'$_GET' => $_GET,
'$_POST' => $_POST,
'$_COOKIE' => $_COOKIE,
'$_FILES' => $_FILES,
'$_ENV' => $_ENV,
'$_REQUEST' => $_REQUEST,
'$_SESSION' => $_SESSION
);
$select_list = '';
foreach (array_keys($superglobals) as $option) {
$select_list .= "\n\t\t\t<option value=\"$option\"";
if (isset($_POST['list'])
and in_array($option, $_POST['list'])
or!isset($_POST['list']) and $option == '$GLOBALS')
$select_list .= ' selected="selected"';
$select_list .= ">$option</option>";
}
?>
<html><head><title>Environment Variables</title></head><body>
<h1>Predefined Variables</h1>
<form action="<?php print $_SERVER['PHP_SELF'];?>" method="post">
<fieldset>
<legend>PHP Superglobals</legend>
<p>PHP provides a large number of
<a href="http://php.net/language.variables.predefined">predefined variables</a>
to any script which it runs.
Many of these variables, however, cannot be fully documented
as they are dependent upon which server is running, the version
and setup of the server, and other factors.
This code snippet is a helper utility to allow you to select and
view these variables. Note that <code>$GLOBALS</code> includes
every other global listed (and more).</p>
<p>
<label for="list">Predefined Variable:</label><br />
<select name="list[]" id="list" multiple="multiple"><?php print $select_list;?>
</select>
</p>
<p><input type="submit" name="Submit" value="Submit" /></p>
</fieldset>
</form>
<?php
foreach ($superglobals as $globalname => $globalvalue) {
if (isset($_POST['Submit'])
and isset($_POST['list'])
and in_array($globalname, $_POST['list'])) {
print "<h1>$globalname</h1>";
print '<pre>';
print_r($globalvalue);
print '</pre>';
}
}
?>
</body></html>


mincklerstraat




msg:1300709
 9:49 am on Oct 27, 2004 (gmt 0)

Nuke those long, aweful switch tables with bulletproof variable functions

You've got this script that's supposed to do any number of things depending on what's coming in via $_POST['do'].

So you set up this ugly long switch table, of course.

switch($_POST['do']){
case 'print': whatever whatever whatever;
break;
case 'display': more of same;
break;
case 'imagine 30 different options here' : a very long and tedious switch table;
break;
}

Well, this can just be plain ugly - I like to have each of these options as nice, self-enclosed functions - that I can also just stick to the end of my php file when I need to add another functionality or option. So, instead, we use bulletproof variable functions that just let us add functions on the fly without having to go and stick them inside this ugly switch table.

$uniqueword = 'uniqueword_';
$funcstring = $uniqeword.$_POST['do'];
if(function_exists($funcstring)) $funcstring();
else {
include_once 'less_commonly_used_funcs_lib.php';
if(function_exists($funcstring)) $funcstring();
else do_error_stuff();
}

Then you just have all of these options wherever you want, probably at the bottom of the file, defined as functions with your $uniqueword as the function name prefix. This little bit extra sets up a simple naming-convention based security, and prevents random things from happening should the words 'exec' or 'unlink' come through in $_POST.

function uniqueword_print(){
global $printheader, $page;
echo $printheader;
echo $page;
}
function uniqueword_display(){
global $query;
etc. etc. ...
}
function uniqueword_someotherfunction(){
etc ...
}

You probably noticed that the above code also tries to find the function in a library file if it's not currently defined. Nice for options that you don't use so often if this is a really, really big list of functions, or if you want to call some function that's used by other files as well.

'bulletproof' is just a hypey term meaning that there is some kind of security provision here, and I myself can't see how a hacker would get around this. I haven't yet used this method in large-scale production, and haven't seen it recommended elsewhere, so use at your own risk.

jatar and coopster: very nice ideas indeed!

jatar_k




msg:1300710
 5:45 pm on Oct 27, 2004 (gmt 0)

another little thing I have used a few times is

Create a Dynamic Table from mysql result

$sql = "select * from sometable"; 
$result = mysql_query($sql);
$tdcount = 1;
$numtd = 3; // number of cells per row
echo "<table>";
while($row = mysql_fetch_array($result)) {
if ($tdcount == 1) echo "<tr>";
echo "<td>some stuff: $tdcount</td>"; // display as you like
if ($tdcount == $numtd) {
echo "</tr>";
$tdcount = 1;
} else {
$tdcount++;
}
}
// time to close up our table
if ($tdcount!= 1) {
while ($tdcount <= $numtd) {
echo "<td>&nbsp;</td>";
$tdcount++;
}
echo "</tr>";
}
echo "</table>";

jatar_k




msg:1300711
 8:28 pm on Oct 27, 2004 (gmt 0)

you can't tell me no one else has any little chunks of script that they use often, don't be shy, simple things are often the greatest ones. Don't feel like anyone will make fun of your snippets or "oh, they probably already know that".

here's another I just wandered into, I drop it into a ton of my personal use forms, I make it prettier for public consumption ;)

Dynamic Date Selector

<?
$today = getdate();
$day = $today['mday'];
// I have my personal ones default to yesterday, so
$day -= 1;
$month = $today['mon'];
$mtharr = array("January","February","March","April","May","June","July","August","September","October","November","December");
?>

<table cellpadding="3" cellspacing="2" border="0"> 
<tr>
<td valign="top">
<select name="sday">
<?
for ($i=1;$i<=31;$i++) {?><?
echo "<option value=\"$i\"";
if ($i == $day) echo " selected";
echo ">$i</option>";
}
?>
</select></td>
<td valign="top">
<select name="smonth">
<?
for ($i=1;$i<=12;$i++) {?><?
echo "<option value=\"$i\"";
if ($i == $month) echo " selected";
echo ">" . $mtharr[$i-1] . "</option>";
}
?>
</select></td>
<td valign="top">
<select name="syear">
<option value="2004">2004</option>
<option value="2003">2003</option>
</select></td>
</tr>
</table>

coopster




msg:1300712
 10:07 pm on Oct 27, 2004 (gmt 0)

strftime

I can't always remember all the format options for the strftime() function. This little snippet comes in handy when I want to get a visual for the one I really need. Hover your cursor over each line to see the format description.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>strftime</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
label {display: list-item;}
</style>
</head>
<body>
<h1>strftime</h1>
<p>Hover your cursor over each of the <a href="http://php.net/strftime">strftime()</a> function format options to see the format description.</p>
<pre>
<?php
$formats = array(
'%a' => "abbreviated weekday name according to the current locale",
'%A' => "full weekday name according to the current locale",
'%b' => "abbreviated month name according to the current locale",
'%B' => "full month name according to the current locale",
'%c' => "preferred date and time representation for the current locale",
'%C' => "century number (the year divided by 100 and truncated to an integer, range 00 to 99)",
'%d' => "day of the month as a decimal number (range 01 to 31)",
'%D' => "same as %m/%d/%y",
'%e' => "day of the month as a decimal number, a single digit is preceded by a space (range ' 1' to '31')",
'%g' => "like %G, but without the century.",
'%G' => "The 4-digit year corresponding to the ISO week number (see %V). This has the same format and value as %Y, except that if the ISO week number belongs to the previous or next year, that year is used instead.",
'%h' => "same as %b",
'%H' => "hour as a decimal number using a 24-hour clock (range 00 to 23)",
'%I' => "hour as a decimal number using a 12-hour clock (range 01 to 12)",
'%j' => "day of the year as a decimal number (range 001 to 366)",
'%m' => "month as a decimal number (range 01 to 12)",
'%M' => "minute as a decimal number",
'%n' => "newline character",
'%p' => "either 'am' or 'pm' according to the given time value, or the corresponding strings for the current locale",
'%r' => "time in a.m. and p.m. notation",
'%R' => "time in 24 hour notation",
'%S' => "second as a decimal number",
'%t' => "tab character",
'%T' => "current time, equal to %H:%M:%S",
'%u' => "weekday as a decimal number [1,7], with 1 representing Monday",
'%U' => "week number of the current year as a decimal number, starting with the first Sunday as the first day of the first week",
'%V' => "The ISO 8601:1988 week number of the current year as a decimal number, range 01 to 53, where week 1 is the first week that has at least 4 days in the current year, and with Monday as the first day of the week. (Use %G or %g for the year component that corresponds to the week number for the specified timestamp.)",
'%W' => "week number of the current year as a decimal number, starting with the first Monday as the first day of the first week",
'%w' => "day of the week as a decimal, Sunday being 0",
'%x' => "preferred date representation for the current locale without the time",
'%X' => "preferred time representation for the current locale without the date",
'%y' => "year as a decimal number without a century (range 00 to 99)",
'%Y' => "year as a decimal number including the century",
'%Z' => "time zone or name or abbreviation",
'%%' => "a literal '%' character"
);
foreach (array_keys($formats) as $format) {
print '<label title="' . $formats[$format] . '">' . "'" . $format . "': " . strftime($format) . "</label>";
}
?>
</pre>
</body>
</html>

[edited by: coopster at 3:06 am (utc) on Feb. 18, 2005]

Robber




msg:1300713
 10:55 pm on Oct 27, 2004 (gmt 0)

Create a Dynamic Table from mysql result

One of the ones above made me think of this, used it earlier today. When you pull results out of a database and present them in a table there often a variable number of blank cell you need to add to complete the table.

$i = 0;
while($row = mysql_fetch_object($selectResult)){
print "a few tables cells in 3 columns blah blah blah";
$i++;
}

$blank_cells = str_repeat('<td>&nbsp;</td>',(ceil($i / $number_of_cols)*$number_of_cols) - $i);

jatar_k




msg:1300714
 3:06 am on Oct 28, 2004 (gmt 0)

slick Robber

jatar_k




msg:1300715
 8:54 pm on Oct 28, 2004 (gmt 0)

Generating a CSV for Download from MySQL

<?
@ob_start();
include "config.php";
$content_file = "";
include "open_db.php";
$content_file .= "cat_id,catname,sequence\r\n";
$sql = 'select * from categories';
$statement = mysql_query($sql);
while($row = mysql_fetch_array($statement)) {
$content_file .= $row['cat_id'] . ',' . $row['catname'] . ',' . $row['sequence'] . "\r\n";
}
$output_file = 'mygreatcsvfile.csv';
@ob_end_clean();
@ini_set('zlib.output_compression', 'Off');
header('Pragma: public');
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: pre-check=0, post-check=0, max-age=0');
header('Content-Transfer-Encoding: none');
//This should work for IE & Opera
header('Content-Type: application/octetstream; name="' . $output_file . '"');
//This should work for the rest
header('Content-Type: application/octet-stream; name="' . $output_file . '"');
header('Content-Disposition: inline; filename="' . $output_file . '"');
echo $content_file;
exit();
?>

I feel like I am talking to myself again ;)

update to this
Export a table to CSV [webmasterworld.com]

[edited by: jatar_k at 2:10 pm (utc) on Feb. 18, 2008]

Birdman




msg:1300716
 9:21 pm on Oct 28, 2004 (gmt 0)

[6]Validate an Email[/6]

function validate_email($email)
{

// Create the syntactical validation regular expression
$regexp = "^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$";

// Presume that the email is invalid
$valid = 0;

// Validate the syntax
if (eregi($regexp, $email))
{
list($username,$domaintld) = split("@",$email);
// Validate the domain
if (getmxrr($domaintld,$mxrecords))
$valid = 1;
} else {
$valid = 0;
}

return $valid;

}

/* Usage:
if(validate_email($_POST['email'])) {
email is valid...
} else {
email not valid..
}*/

It checks for MX record as well!

rysolag




msg:1300717
 7:42 am on Oct 29, 2004 (gmt 0)

Form a single string throughout the script that represents the HTML to be returned. This way you can use header() anywhere in your code. For example:


$r = "";
$r .= "<html><head></head>";
$r .= "<body>";

$r .= "part of the body";

if(true)
header("Location: http://www.example.com/");

$r .= "more body";

$r .= "</body>";
$r .= "</html>";

//don't forget to print it
print $r;

eggy ricardo




msg:1300718
 1:05 pm on Oct 29, 2004 (gmt 0)

rysolag - maybe i misunderstood but doesn't output buffering do the same thing? (or maybe i've misunderstood output buffering :))

Cheers
Richard

mincklerstraat




msg:1300719
 1:33 pm on Oct 29, 2004 (gmt 0)

Output buffering does something similar, but is a bit more of a 'round about' method, rysolag's is straightforward and probably better if you are coding from scratch - output buffering is great when you later realize, 'ouch, I have output here but the code I need for headers / cookies comes later'! Or when you need to modify the page output with a few ad-hoc find-replaces.

ukgimp




msg:1300720
 1:52 pm on Oct 29, 2004 (gmt 0)

Jatar with respect to your CSV downloader, should it create a file for downloading of just render the results in the browser. If it is fro creating a csv to download like what happens when you click on a exe download button I cant get it to work.

Cheers

jatar_k




msg:1300721
 5:16 pm on Oct 29, 2004 (gmt 0)

it creates the file for download only and prompts with an 'open/save as' dialog.

I have reposted the code with the actual test version I used just now and it owrked for me in IE, moz, firebord and opera.

what is the behaviour, ukgimp?

jatar_k




msg:1300722
 10:38 pm on Nov 2, 2004 (gmt 0)

needed this today

getting information about mysql tables and fields

<? 
mysql_connect($dbhost, $dbuser, $dbpw);
mysql_select_db($dbname);
$result = mysql_list_tables($dbname);
while ($row = mysql_fetch_row($result)) {
echo "<p><b>Table: $row[0]</b>\n";
$result2 = mysql_query("SHOW COLUMNS FROM " . $row[0]);
if (mysql_num_rows($result2) > 0) {
while ($row = mysql_fetch_assoc($result2)) {
echo '<br>',$row[Field],' : ',$row[Type];
//echo "<pre>";
//print_r($row);
//echo "</pre>";
}
}
}
?>

you can use the commented print_r for full info

coopster




msg:1300723
 8:28 pm on Nov 8, 2004 (gmt 0)

Control your included files

Wouldn't it be nice to just include() [php.net] your files and never have to worry about the path? You set it once when you setup a new site and be done with it. A lot of programmers use this technique, you'll often see it called the "config.php" script or something similar. Here's a sample to get you started (replace the bold path with the path to your includes directory):

ini_set [php.net]('include_path [php.net]', 
realpath [php.net]($_SERVER [php.net]['DOCUMENT_ROOT'] . '/../includes/')
. PATH_SEPARATOR [php.net]
. ini_get [php.net]('include_path'));

Some pretty neat stuff going on in here.

First, notice the use of the realpath() function to put the canonicalized absolute pathname together from a relative link (/../includes/), which by the way, resides below the public document root ;) -- tidies it up quite nicely.

Second, we concatenate the current server configuration include_path to the end of our include_path. Why? In case you want to use any existing paths, such as PEAR classes.

Lastly, notice the use of the PATH_SEPARATOR predefined constant? That way you can use it on a Windows server or a *nix server without having to modify anything.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved