Forum Moderators: coopster

Message Too Old, No Replies

Php bag of tricks

Favorite php tricks on your site

         

copongcopong

11:05 pm on Nov 11, 2002 (gmt 0)

10+ Year Member



Hi everyone, I am reading on this thread ...

www.webmasterworld.com/forum21/3697.htm

and i find some simple php scripts that are very cheesey and said to myself why didn't i think about that!

How about posting your php tricks on your site like link management or everything under the sun which would be very helpful for all in creating dynamic sites and even for newbies.

peace. :)

[edited by: jatar_k at 4:10 pm (utc) on Mar. 29, 2003]

andreasfriedrich

9:58 pm on Nov 16, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The FT has one: Exchange rate Canadian Dollar -> Euro [mwprices.ft.com]

toadhall

10:20 pm on Nov 16, 2002 (gmt 0)

10+ Year Member



6.27!? You can't get a beer for 6.27 in Berlin can you?
Anyway, how 'bout this Mr. Fancy-pants - I can get the same result with good old fashioned conditionals:

<?
if (!$page ĶĶ $page == "") {
echo "index";
} elseif ($page == "aaron") {
echo "Aaron rules";
} elseif ($page == "jesse") {
echo "Jesse rules";
} else {
echo "page does not exist";
}
?>

...put *that* in your stein and chug it! ;)

[edited by: toadhall at 11:25 pm (utc) on Nov. 16, 2002]

andreasfriedrich

11:12 pm on Nov 16, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Mr. Fancy-pants, hehe ... me thinks not.

You can't get a beer for 6.27 in Berlin can you?

If you go to a bar for Fancy-Pants then you canīt. But there are enough places where you still get two pints for that. Itīs not enough to get "pissed" though. In general Berlin is a lot cheaper than most German cities such as Munich or Frankfurt.

put *that* in your stein

Donīt have one. Iīm not in Bavaria.

I can get the same result with good old fashioned conditionals

True enough, but not with the code you posted. ;) If $page is not set or is empty then $page is set to index and the rest of your conditional statement is never evaluated. [edited]This was true until toadhall changed his code. Now donīt tell him this, but his code still wonīt do what he thinks it does when $page='index'.[/edited]

if (!$page && $page == "") {  
$page = "index";
}
#
if ($page == "aaron") {
echo "Aaron rules";
# many lines of code
} elseif ($page == "jesse") {
echo "Jesse rules";
# many lines of code
} else {
# many lines of code
echo "page does not exist";
}

will work as you intended but is really hard to read. Now have a look at this code:

<?php 
$pages = array('index' => 'index',
'aaron' => 'aaron',
'jesse' => 'jesse'
#
if (!isset($_GET['page']) or empty($_GET['page']))
$_GET['page'] = 'index';
#
if (function_exists($pages[$_GET['page']])) {
$pages[$_GET['page']]();
} else {
echo 'page does not exist';
}
#
function aaron() {
echo "Aaron rules";
# many lines of code
}
#
function jesse() {
echo "Jesse rules";
# many lines of code
}
#
function index() {
echo "index";
# many lines of code
}
?>

Just beautiful and soo easy to read. :) [edited after adamīs edit]Now that my point is no longer clearly visible (sometimes a visual approach seems to be so much clearer than the more abstract description) I need to put it into words: Using a function table makes for much clearer code since the basic structure of a script becomes apparent from just a few lines of code. Of course you could use use function calls within the conditional, but for more than a few conditions this is still harder to read than the function table approach.[/edited] BTW it was you who wanted to use variable functions in the first place. So stop picking on me. ;)

TMTOWTDI in PHP as well. This will get even better the more features are added to PHP.

Andreas

[edited]BTW, did you know that one can remove the edited by notice[/edited]
[edited by: ->jatar_k<- at 11:47 pm (utc) on Nov. 16, 2005]

[edited by: andreasfriedrich at 12:15 am (utc) on Nov. 17, 2002]

toadhall

11:38 pm on Nov 16, 2002 (gmt 0)

10+ Year Member



>TMTOWTDI
wha?

> ...but not with the code you posted
I managed to mis-speak myself twice in one morning, BUT, I beat the 'owner edit' time-out.

>Donīt have one. Iīm not in Bavaria
That crossed my mind only after I hit the submit button. Excuse? Oh yeah,... Mother's from Stuttgart, and nothing spells Stein quite like Stuttgart! ;)

Declaration:
Next time I'm in Berlin I'll buy you a beer, or two, depending on the locale. Which may be a while, given the state of the world.

A friend boarding another friend's daughter here in Victoria has just told me her parents (Berliners btw) don't want her flying home for Christmas. Too risky.

jatar_k

11:44 pm on Nov 16, 2002 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



I didn't realize you were in Victoria toadhall, I just might be able to buy you a beer sometime, me being in Vancouver and all.

toadhall

11:59 pm on Nov 16, 2002 (gmt 0)

10+ Year Member



Please, Jatar, let me come visit you in Vancouver. Any excuse to get off this rock for a few days! Then again, I might melt or something. So, sure, come to Oak Bay. There's a ye olde pubette in the "village" called Penny Farthing with Guiness and Harp on tap. Inside it's more Dublin than London and Monday's 2 for 1 halibut and chips.
A former Irish Rover sings there now and again.
The servers wear black.
It's within crawling distance of home.

andreasfriedrich

12:33 am on Nov 17, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



>TMTOWTDI
wha?

TMTOWTDI [catb.org]


;) Please limit off topic discussions to the foo forum. Thanks. ;)

Next time I'm in Berlin I'll buy you a beer, or two, depending on the locale

Looking forward to that.

Andreas

[edited by: jatar_k at 12:22 am (utc) on Jan. 28, 2004]
[edit reason] fixed an outdated url [/edit]

aspr1n

1:17 am on Nov 17, 2002 (gmt 0)

10+ Year Member



toadhall,

Coming from a C background that's like assigning functions to NULL pointers, create an array of NULL pointers and now you have a great way of creating a Finite State Machine.

Now why anyone would want to do that in PHP... ;)

BTW. I accept cheques, mastercard or buttons.

asp

toadhall

2:12 am on Nov 17, 2002 (gmt 0)

10+ Year Member



One more before I go out and check on the barn (there's a gale blowing tonight):

If you need to hide anything on your page, or at least make it illegible or at least unreadable (say an answer to a riddle or the ending to a book) without actually obliterating it, use str_rot13()

$str = "Don't you just hate being treated like a child?";
str_rot13($str);

Now $str will result in...
Qba'g lbh whfg ungr orvat gerngrq yvxr n puvyq?

str_rot13 stands for "string rotation 13" - it rotates the alpha characters 13 places.
To rotate them back just repeat the same line...
str_rot13($str);

And $str will return to...
Don't you just hate being treated like a child?

aspr1n:
Finite State Machines might as well be liver and onions - just not on my menu. Or, to mix metaphors, over my head. I googled it and read but... perhaps another lifetime. ;)

dingman

6:45 am on Nov 17, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Finite State Machines might as well be liver and onions - just not on my menu. Or, to mix metaphors, over my head. I googled it and read but... perhaps another lifetime.

If you program at all, in any language, you are producing FSMs. You're just not using any inconveniently theoretical method of so doing, and probably would have a hard time coming up with an explicit listing of all your machine's states. It'd be a bear to write out any of my useful programs in the form of an FSM but I've worked through the proof and believe it. (See, I got something out of my $80k educational loans, really I did.)

aspr1n

1:08 pm on Nov 17, 2002 (gmt 0)

10+ Year Member



[ Off Topic Sidebar ]

FSMs are great for programs that have a set number of states, for example to write protocol engines.

You need to consider it right from the initial design phase, but you describe on a flow chart the logical seqential steps of execution thus:

a() {
do stuff
if ( i == x )
b(i);
else c(i);
}

b(i) {
do stuff
if ( i == y )
c(i);
else d(i);
}

instead you could just:

a() {
do stuff
func[i];
}

etc etc

By placing the function pointers into an array, you can jump through the entire program without calling a specific funtion by using the array subscript value to determine what is called.

In C as the funtions are just 4 byte pointers execution speed is very fast, though there are issues with chips having to flush cache pipelines more frequently due to a lack of any traditional sequential program execution.

They are quite cool tools, and can generate very tight code that is easy to maintain.

asp

jaski

4:39 pm on Nov 17, 2002 (gmt 0)

10+ Year Member



One of the most useful library functions I find myself using so often is this

function select_string($array_input,$name,$selected)
{
$retstring .= "<select name = $name>";
if(is_array($array_input))
{
foreach ($array_input as $key => $value)
{
$retstring .= "<option value = '$key'";
if($selected == $key)
{
$retstring .= " selected";

}
$retstring .= ">$value\n";
}
}
$retstring .= "</select>\n";
return $retstring;
}

Documentation
This function is used to create drop down lists(select option tags) for using in forms.

$array_input is an associative array of all the key/value pairs.

$name has the name you want to give to the <select> tag which will in turn become a variable which will store value of selected option when the form is submitted.

$selected is the value you want as the preselected value in the list.

There are number of advantages of this approach.
1) I have a reusable standard function for a standard task.
2) When the form submitted has some errors and needs to be sent back to the user for corrections .. its very easy to recreate select list with the values user filled in the last attempt

eg . $select_list = select_string($array_name,'name',$name);
where 'name' is the name of the variable .. and $name is the value which user submitted in the last attempt ..

As I said .. I find this to be one of the most reused pieces of code in my applications.

Jaski :)

PS: I am sorry about the formatting .. I could not figure out how to format it for proper display here in the forum..it seems to strip the tabs and spaces.

toadhall

7:38 pm on Nov 17, 2002 (gmt 0)

10+ Year Member



Nice code jaski, thanks.
For any newbies having trouble with getting it to go use something like this:

$array_input = array("ca"=>"Canada","cr"=>"Costa Rica","de"=>"Germany","uk"=>"United Kingdom");
$name = "countries";
$selected = "uk";
echo select_string($array_input,$name,$selected);

Again, thanks jaski.

jatar_k

7:55 pm on Nov 17, 2002 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



how about a little extension on that one

this looks for the client's directory gets all of the filenames, cuts off the file extension and lists them in a drop down.

$reportpath = $DOCUMENT_ROOT . $client . "/";
$d = dir($reportpath);
$report_list = array();
$index = 0;
while($filename = $d->read())
{
if ($filename!= "." && $filename!= "..") {
$report_list[$index] = $filename;
$index++;
}
}
?>
<FORM NAME="" METHOD=GET ACTION="somescript.php">
<B>Choose Report</B>
<BR><SELECT NAME="repdate">
<?
foreach ($report_list as $key => $value) {
$match = preg_split('[\.]',$value);
$fmonth = $match[0];
?>
<OPTION VALUE="<?= $fmonth?>" <? if ($fmonth == $repdate) echo "SELECTED";?>><?= $fmonth?></OPTION>
<?
}
?>

some of it is a little lazy but it works well

toadhall

9:44 pm on Nov 17, 2002 (gmt 0)

10+ Year Member



On the topic of opendir(), how about a quick and dirty menu maker?

$this_file = basename($REQUEST_URI);
list($this_ffile) = split("\.",$this_file);
$thisfile = str_replace("_"," ",$this_ffile);
$ThisFile = ucwords($thisfile);
$menu = array();
$dir = opendir(".");
while ($file = readdir($dir)) {
array_push($menu,$file);
}
sort($menu);
while(list (,$link) = each ($menu)) {
list ($linkname,$ext) = split("\.", $link,2);
/* next line excludes this directory and all gif images. Exclude by file extension ($ext), by filename and extension ($link), or by filename ($linkname) */
if ($link!= "." && $link!= ".." && $link!= $this_file && $ext!= "gif") {
$linkname = str_replace("_"," ",$linkname);
$linkname = ucwords($linkname);
echo (" Ķ <a href=\"$link\">$linkname</a>");
}
}
echo " Ķ ";

NB - Replace all the pipes (Ķ) with fresh ones before using.

andreasfriedrich

12:40 am on Nov 18, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Adamīs way of building the option elements made me wonder about the cost of repeatedly switching between html and php mode. I admit Iīm a bit baffled by my findings:

trick

Use PHPīs feature to easily switch between html and php mode whenever you want/need to. This comes at very little cost. When you need to output just a single variable use <?=$var?> instead of <?echo $var?>.

The printf() approach was faster once more than 8 variables were used to build the option elements.

data

html/php mode (<?=)...: 0.2423449754715 
html/php mode (<?echo): 0.25177192687988
printf()..............: 0.27242302894592

benchmark

<?php 
function getmicrotime($t) {
list($usec, $sec) = explode(" ",$t);
return ((float)$usec + (float)$sec);
}
#
$reportpath = $DOCUMENT_ROOT . $client . "/";
$d = dir($reportpath);
$report_list = array();
$index = 0;
while($filename = $d->read()) {
if ($filename!= "." && $filename!= "..") {
$report_list[$index] = $filename;
$index++;
}
}
?>
<form><select name="repdate">
<?
$start = microtime();
for($i=0; $i<100; $i++) {
foreach ($report_list as $key => $value) {
$match = preg_split('[\.]',$value);
$fmonth = $match[0];
// uncomment to get printf version
# printf('<option value="%s" %s>%s</option>',
# $fmonth, $fmonth == $repdate? 'selected="selected"':'',
# $fmonth);
?>
<option value="<?echo $fmonth?>"
<? if ($fmonth == $repdate) echo 'selected="selected"';?>
><?echo $fmonth?></OPTION>
<?
}
}
$end = microtime();
?></select></form>
#
<?
echo (getmicrotime($end) - getmicrotime($start));
?>

Andreas

gloescher

4:59 pm on Nov 18, 2002 (gmt 0)



Hi folks,
New to this place--lots of good stuff here!

Just a little function I use for debugging, because I got tired of typing pre..print_r../pre all the time:


function dump($label, &$var) {
echo '<h2>', $label, '</h2>';
echo '<hr size="1" noshade />';
echo '<pre>';
print_r($var);
echo '</pre>';
}

Of course, change the formatting to taste :)
Cheers,
Gary

mvl22

6:30 pm on Nov 18, 2002 (gmt 0)

10+ Year Member



No question: auto_prepend_file and auto_append_file directives:

stick

php_value auto_prepend_file /startofhousestyle.html
php_value auto_append_file /appended.html

in your .htaccess or server config, and these two files will <strong>automatically</strong> get stuck in front and at the end of each page. Imagine, you don't now have to stick includes into every file, e.g.

/contacts/

becomes

Site name > Contact details

as your browser title, and in your navigation line could be

You are in: Home > Contact details

with links under the words, etc.

Put a short script in your starting file which converts a directory structure into words, i.e. looks up the URL, changes each bit between the slashes into text, and you can then generate navigation lines, open the correct menu, give the window a browser title, etc,. all automatically.

I have 30 or so sites that use this, if anyone wants to sticky me for an example or two. Each have been set up in a ridiculously short space of time because of it.

Why is this feature so little known about or used? It's revolutionary.

jatar_k

6:52 pm on Nov 18, 2002 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



Welcome to WebmasterWorld gloescher

Xuefer

5:15 pm on Nov 19, 2002 (gmt 0)

10+ Year Member




Use single quoted strings unless you need to interpolate variables into your string

php scan the code at "compile"(scan) time, then execute it, doesn't it?
then signle/double quote should be different in compile time, not run-time.
i think, it's php can be more optimize on handling single/double quotes
meant that, when scanning code, if double quote has no $var in it, should be process same as single quote

andreasfriedrich

6:12 pm on Nov 19, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Welcome to WebmasterWorld [webmasterworld.com], Xuefer.

You are right.

  • PHP does check whether double quoted strings contain variables to be interpolated.
  • Runtime of double quoted strings without variables in them is the same as single quoted strings.
  • While double quoted strings would require more work on intial parsing of the code, there was no measurable speed difference.

Andreas

Xuefer

2:14 am on Nov 20, 2002 (gmt 0)

10+ Year Member



thx
then why we get faster on single quote?

problem 2:
using concat: 0.0043810606002808
seconds using array.: 0.0063339471817017 seconds
difference..: -0.0019528865814209 seconds
this is my result, processing 1000 elements in PII866

why u get different result than me?
cos... u didn't initize $s

when first time $s .= "...."; it trigger php's error system
losing time!

$s = '';
$s1 = microtime(); foreach($x as $val) { $s .=

this DOES faster than array/join

andreasfriedrich

9:51 am on Nov 20, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There was no measurable difference in runtime depending on whether $s was initialized or not. So I do not believe this to be sufficient to account for our differing results.

It is true, however, that for larger data sets (processing 1000 elements) the concatenation approach is faster. For small data sets (>26) the script ran faster using the push/join approach.

Andreas

dingman

6:07 pm on Nov 20, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Anyone know whether the cost of double quotes applies every time the script is called or whether it gets optimized out and stored that way when using APC or the Zend cache? I don't have comparable machines to test on, but it seems like an easy optimization and a place where caching could realy be beneficial for a lot of people.

jaski

5:20 am on Nov 21, 2002 (gmt 0)

10+ Year Member



Is the difference in single and double quotes significant enough to be a performance issue. I use them purely on the basis of which one I need .. concatenations usually clutter up the code so I often use <<<EOD operator for variable interpolation .. I suppose it is also similar to double quotes as far as performance is concerned.

I don't think variable interpolation efficiency could practically ever be a bottleneck in any application...so I give priority to reducing clutter over performance.


Part 2
Bag-O-Tricks for PHP II [webmasterworld.com]

[edited by: jatar_k at 11:21 pm (utc) on June 28, 2003]
[edit reason] updated link [/edit]

This 55 message thread spans 2 pages: 55