
02-01-2007, 12:03 AM
|
|
Web Hosting Guru
|
|
Join Date: Dec 2005
Posts: 326
|
|
Open file and replace in php
Hi,
I'm making a simple Template system for a script I'm making. I want to know how by using the fopen function to open the file with read and write permissions can I search for things like "{Header}" or something like that, and replace it with certain content. I'd be opening an HTML file, and only want to replace the content displayed, not the physical file....
any help is appreciated!
|

02-01-2007, 12:36 AM
|
|
Web Hosting Guru
|
|
Join Date: Dec 2005
Posts: 326
|
|
I can't seem to edit my post... I might've found a solution using "preg_replace()" function.
PHP Code:
<?php $string = fopen('$template', 'r'); $patterns[0] = '{Header}; $patterns[1] = '{Footer}'; $patterns[2] = '{Content}'; $replacements[2] = 'Content here'; $replacements[1] = 'Test Footer'; $replacements[0] = 'Banner here maybe'; echo preg_replace($patterns, $replacements, $string); ?>
What do you guys think?
|

02-01-2007, 11:46 AM
|
|
Web Hosting Guru
|
|
Join Date: Nov 2003
Posts: 297
|
|
fopen('$template', 'r');
wil return a handle to the open file. you need to use fread to read the file contents to a string..
PHP Code:
$handle=fopen($file, 'r'); $contents=fread($handle, filesize($file)); fclose($handle); echo $contents;
edit - also '$template' should not be in quotes if it is a variable
|

02-01-2007, 12:26 PM
|
|
CEO - JaguarPC
|
|
Join Date: Jul 2000
Location: Colorado Springs, CO
Posts: 2,205
|
|
Another thing you can do is build it as an object instead of reading it and then parse through it.
PHP Code:
ob_start();
include("template.file");
$file = ob_get_contents();
ob_end_clean();
now do whatever you want with the file.
PHP Code:
$patterns[0] = '{Header};
$patterns[1] = '{Footer}';
$patterns[2] = '{Content}';
$replacements[2] = 'Content here';
$replacements[1] = 'Test Footer';
$replacements[0] = 'Banner here maybe';
echo preg_replace($patterns, $replacements, $file );
__________________
Hosting solutions provider since 1998 - Serving over 130 countries!
JaguarPC.com - Managed web hosting | Managed vps hosting | Dedicated servers
Resellerzoom.com - Reseller specialist | Cloud Reseller hosting | cPanel cloud Hosting
|

02-01-2007, 12:50 PM
|
|
Corporate Member
|
|
Join Date: Aug 2004
Location: Canada
Posts: 3,182
|
|
Ok here's a basic example of a poor mans template system
PHP Code:
<?php
// Open the file
$handle=fopen($file, 'r');
$contents=fread($handle, filesize($file));
fclose($handle);
/*
Use an array of $array[$k]=$v;
Example:
{var} we want it to become "BLAH"
We would do
$array['var']="BLAH";
*/
// Once we got our entire array of replacements loop through them all
foreach ($array AS $k => $v)
{
$contents=str_replace("{".$k."}",$v,$contents);
}
print $contents;
?>
It does the job probably better to make an entire class and have a bunch of functions to handle each operation. Not really that fast really should use a template system like smarty if you want to go that route.
__________________
█ Tony B. - Chief Executive Officer
█ Hawk Host Inc. Proudly serving websites since 2004
█ Quality Shared and VPS Hosting
█ PHP 5.3.x & PHP 5.4.x & PHP 5.5.X Support!
|

02-01-2007, 01:06 PM
|
|
Hail Eris !
|
|
Join Date: Oct 2002
Location: Canada
Posts: 3,100
|
|
Forget about "poor mans template system" in the post above. It is never good idea to loop if it can be avoided. Additionally according to php docs, file_get_contents() is more efficient then other ways to read the file so why not use it.
PHP Code:
$file = 'myfile.html' ;
$startTag = '{' ;
$endTag = '}' ;
$tokens = array () ;
$tokens['header'] = 'This is some header' ;
$tokens['footer'] = 'And here is footer' ;
$html = preg_replace ("/".$startTag."(\w+)".$endTag."/e" , "\$tokens['\\1']" , file_get_contents($file) ) ;
|

02-01-2007, 03:12 PM
|
|
Corporate Member
|
|
Join Date: Aug 2004
Location: Canada
Posts: 3,182
|
|
But then you need to remember regular expressions are slower so there is probably no difference between the two in terms of speed. It's purely preference
Of course I may be mistaken.
__________________
█ Tony B. - Chief Executive Officer
█ Hawk Host Inc. Proudly serving websites since 2004
█ Quality Shared and VPS Hosting
█ PHP 5.3.x & PHP 5.4.x & PHP 5.5.X Support!
|

02-01-2007, 06:11 PM
|
|
Web Hosting Guru
|
|
Join Date: Dec 2005
Posts: 326
|
|
I'm going to try some of these a bit later and see if any of them works for me!
Thanks for the replies
|

02-01-2007, 06:35 PM
|
|
iNET Interactive
|
|
Join Date: May 2001
Location: Dayton, Ohio
Posts: 4,869
|
|
Quote:
|
Originally Posted by TonyB
But then you need to remember regular expressions are slower so there is probably no difference between the two in terms of speed. It's purely preference
Of course I may be mistaken.
|
I decided to do a very quick and dirty benchmark on both of these systems. I created a basic HTML template which was used by both systems. I then used a simple PHP class to gauge the execution time of both scripts. The server this was done on has zero load and is used for my development tasks.
Here is the HTML template:
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Test Document</title>
</head>
<body>
<p>{header}</p>
<p>Something goes in between here (up) and there (down)! </p>
<p>{footer}</p>
</body>
</html>
Here are the test files I ran:
PHP Code:
[root@linux test]# cat test1.php <?php require_once('class.timer.php'); Script_Timer::Start_Timer();
$file = 'template.html'; $startTag = '{'; $endTag = '}'; $tokens = array (); $tokens['header'] = 'This is some header'; $tokens['footer'] = 'And here is footer'; $html = preg_replace ("/".$startTag."(\w+)".$endTag."/e" , "\$tokens['\\1']" , file_get_contents($file) );
echo "Script Execution Time: "; echo Script_Timer::Get_Time(); //echo "\n\n"; //echo $html; echo "\n";
PHP Code:
[root@linux test]# cat test2.php <?php require_once('class.timer.php'); Script_Timer::Start_Timer();
$file = 'template.html'; // Open the file $handle=fopen($file, 'r'); $contents=fread($handle, filesize($file)); fclose($handle);
/* Use an array of $array[$k]=$v;
Example: {var} we want it to become "BLAH"
We would do $array['var']="BLAH"; */
$array['header'] = "This is some header"; $array['footer'] = "And here is footer";
// Once we got our entire array of replacements loop through them all foreach ($array AS $k => $v) { $contents=str_replace("{".$k."}",$v,$contents); }
echo "Script Execution Time: "; echo Script_Timer::Get_Time(); //echo "\n\n"; //echo $contents; echo "\n";
And here are my results:
TonyB's Code
Code:
[root@linux test]# php test2.php; php test2.php; php test2.php; php test2.php; php test2.php; php test2.php; php test2.php; php test2.php; php test2.php; php test2.php;
Content-type: text/html
Script Execution Time: 0.0001769066
Content-type: text/html
Script Execution Time: 0.0001759529
Content-type: text/html
Script Execution Time: 0.0001759529
Content-type: text/html
Script Execution Time: 0.0001778603
Content-type: text/html
Script Execution Time: 0.0001790524
Content-type: text/html
Script Execution Time: 0.0001740456
Content-type: text/html
Script Execution Time: 0.0001740456
Content-type: text/html
Script Execution Time: 0.0001749992
Content-type: text/html
Script Execution Time: 0.0001740456
Content-type: text/html
Script Execution Time: 0.0001740456
[root@linux test]#
sasha's code:
Code:
[root@linux test]# php test1.php; php test1.php; php test1.php; php test1.php; php test1.php; php test1.php; php test1.php; php test1.php; php test1.php; php test1.php;
Content-type: text/html
Script Execution Time: 0.0002691746
Content-type: text/html
Script Execution Time: 0.0002660751
Content-type: text/html
Script Execution Time: 0.0002648830
Content-type: text/html
Script Execution Time: 0.0002651215
Content-type: text/html
Script Execution Time: 0.0002639294
Content-type: text/html
Script Execution Time: 0.0002639294
Content-type: text/html
Script Execution Time: 0.0002658367
Content-type: text/html
Script Execution Time: 0.0002648830
Content-type: text/html
Script Execution Time: 0.0002651215
Content-type: text/html
Script Execution Time: 0.0002648830
[root@linux test]#
These are not the most scientific benchmarks and load times might differ depending on the size of the file being parsed. But I don't have time to do that deep of testing :)
__________________
-Mat
Last edited by The Prohacker; 02-01-2007 at 06:38 PM.
|

02-01-2007, 07:27 PM
|
|
Hail Eris !
|
|
Join Date: Oct 2002
Location: Canada
Posts: 3,100
|
|
With tiny file and only couple replacements results are too fast to matter. Actual benefit in performance you get as your file grows and there are more strings to replace. FOR loop will have to re-parse file once for each additional string. preg_match will do single pass regadless whether you have one replacement or 30 replacements. Consider situation where you have to display 30 products on the page and use product template that could look something like this:
Code:
{Product_Name}
<br>
{Product_Image}
<br>
{Product_price}
<br>
{Product_saleprice}
<br>
{Product_ID}
<br>
.........
For loop would parse that file 30 * 5 = 150 times. Preg_match would do it once for each product = 30 times.
|

02-01-2007, 08:08 PM
|
|
Web Hosting Master
|
|
Join Date: Mar 2006
Posts: 961
|
|
PHP Code:
$patterns[0] = '{Header};
for:
PHP Code:
$patterns[0] = '{Header}';
As for parsing tags from variables, here's a sample function I like very much from 4images gallery script:
PHP Code:
var $start = "{"; var $end = "}";
function print_template($template) { if (strpos($template, $this->start.'header'.$this->end) !== false) { $header = $this->parse_template("header"); $template = str_replace($this->start.'header'.$this->end, $header, $template); }
if (strpos($template, $this->start.'footer'.$this->end) !== false) { $footer = $this->parse_template("footer"); $template = str_replace($this->start.'footer'.$this->end, $footer, $template); }
print $this->clean_template($template); }
Recall: This is only a token sample from one of the class files.
|

02-01-2007, 08:19 PM
|
|
Corporate Member
|
|
Join Date: Aug 2004
Location: Canada
Posts: 3,182
|
|
It would pass that 150 times but loops do not mean that it's going to be slower. string replacements are very fast compared to regular expression replacements. Add to the fact the data is already in memory going through it is very easy. What is tough is regular expression part which is on the CPU itself. At least that's how I understand about strings.
If someone cares enough they can load up a large file and lots of replacements and see if it even makes a difference.
I mean I use smarty for template needs parsing something like this everytime is slow anyways and is a bad way to do things to begin with.
__________________
█ Tony B. - Chief Executive Officer
█ Hawk Host Inc. Proudly serving websites since 2004
█ Quality Shared and VPS Hosting
█ PHP 5.3.x & PHP 5.4.x & PHP 5.5.X Support!
|

02-05-2007, 09:44 PM
|
|
Web Hosting Master
|
|
Join Date: Aug 2002
Location: Canada
Posts: 644
|
|
Hi Matt,
Good to see you poking around! I'd be interested in the results of a single str_replace statement for your second codeblock on that same machine, using file_get_contents instead of the socket-based handle:
PHP Code:
<?php require_once('class.timer.php'); Script_Timer::Start_Timer();
$contents = file_get_contents( 'template.html' );
// left these for good measure $array['header'] = "This is some header"; $array['footer'] = "And here is footer";
// build search/replace arrays $search = array(); $replace = array();
foreach( $array as $k => $v ){ array_push( $search, "{".$k."}" ); array_push( $replace, $v ); }
// single call $contents = str_replace( $search, $replace, $contents );
echo "Script Execution Time: "; echo Script_Timer::Get_Time(); //echo "\n\n"; //echo $contents; echo "\n"; ?>
Cheers.
Alex
|

02-06-2007, 09:28 AM
|
|
Hail Eris !
|
|
Join Date: Oct 2002
Location: Canada
Posts: 3,100
|
|
Quote:
|
Originally Posted by TonyB
It would pass that 150 times but loops do not mean that it's going to be slower. string replacements are very fast compared to regular expression replacements. Add to the fact the data is already in memory going through it is very easy. What is tough is regular expression part which is on the CPU itself. At least that's how I understand about strings.
If someone cares enough they can load up a large file and lots of replacements and see if it even makes a difference.
I mean I use smarty for template needs parsing something like this everytime is slow anyways and is a bad way to do things to begin with.
|
Ok, if you want to avoid regular expressions you can still do parsing in single pass with no looping. Again I doubt it will matter much on small file with only couple replacements but personally i deem loops evil and try to avoid them
The problem with function below though is that if will not remove tokens you do not set, so if you have something like {special_header} and you do not specify replacement for it, it will show up as is. I think that could have been the main reason I decided to use regular expressions in my template class.
PHP Code:
$file = 'myfile.html' ;
$tokens = array () ;
$tokens['header'] = 'This is some header' ;
$tokens['footer'] = 'And here is footer' ;
$paterns = array_keys ($tokens) ;
$replacements = array_values ($tokens);
array_walk ($paterns , 'enclose');
$html = str_replace ($paterns , $replacements , file_get_contents($file));
function enclose (&$item){
$startTag = '{' ;
$endTag = '}' ;
$item = $startTag . $item . $endTag ;
}
|

02-06-2007, 05:16 PM
|
|
Corporate Member
|
|
Join Date: Aug 2004
Location: Canada
Posts: 3,182
|
|
I see your point you don't really need to use php based loops but technically the functions you call are doing loops as well.
So there is no way to avoid the thing doing some sort of loop.
__________________
█ Tony B. - Chief Executive Officer
█ Hawk Host Inc. Proudly serving websites since 2004
█ Quality Shared and VPS Hosting
█ PHP 5.3.x & PHP 5.4.x & PHP 5.5.X Support!
|
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Linear Mode
|
| Postbit Selector |
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|
|
| Login: |
|
|
| Advertisement: |
|
|
| Web Hosting News: |
|
|
|