View Full Version : Str_replace not working?
blu3t00th
05-02-2008, 02:55 AM
Ok so I have a template system
Here is the a part of the template class
function assign_block_vars($blockname, $tags = array()){
if(isset($this->blocks[$blockname])){
$blockCode = $this->blocks[$blockname];
}else{
$blockCode = $this->get_block($blockname);
}
foreach ($tags as $tag => $data) {
$blockCode = str_replace ("{".$blockname.".".$tag."}", $data, $blockCode);
}
$this->template = str_replace ('<!-- END '.$blockname.' -->', $blockCode.'<!-- END '.$blockname.' -->', $this->template);
}
function get_block($block){
preg_match ('#<!-- START '. $block . ' -->(.*?)<!-- END '. $block . ' -->#s', $this->template, $this->return);
$this->blocks[$block] = $this->return[1];
$this->template = str_replace($this->return[1], '', $this->template);
return $this->blocks[$block];
}
function Output(){
return($this->template);
}
Here is a sample from a template file
<div class="menu">
<ul>
<!-- START Menu -->
<li><a href="{Menu.Linkto}">{Menu.Link}</a></li>
<!-- END Menu -->
</ul>
</div>
Here is a sample from the page were it all happens
$Menu = array( 0 => array("Home", //Looping Data [Main Mavigation Tabs]
ROOT_PATH . "index.php",),
1 => array("Register",
ROOT_PATH . "broken.php",),
2 => array("Forums",
ROOT_PATH . "broken.php",),
3 => array("Tutorials",
ROOT_PATH . "broken.php",),
4 => array("Affiliates",
ROOT_PATH . "broken.php",),
5 => array("About",
ROOT_PATH . "broken.php",),
6 => array("Contact",
ROOT_PATH . "broken.php",));
while(list($key, $value) = each($Menu)){ //Replaces results and loops
$template->assign_block_vars("Menu", array("Link" => $value[0],
"Linkto" => $value[1]));
}
My problem is, When I try and replace <-- START xxxxxx --> LOOP <-- END xxxxxx --> It replaces fine, But it doesnt remove the html comment like it should, Any reason why it might not be doing that?
I have it a feeling it might have something to do with my replacing part
$this->template = str_replace ('<!-- END '.$blockname.' -->', $blockCode.'<!-- END '.$blockname.' -->', $this->template);
Everything works fine, I just want the html comments removed thats all, and it dont not seem to be doing that
If you want more of the class let me know
Thanks
Instead of using str_replace(), try using filesystem functions (http://www.php.net/manual/en/ref.filesystem.php).
blu3t00th
05-02-2008, 03:30 AM
I dont quite get what you mean.. Everything it working fine with the class and its replacing loops like it should, Its just not removing the html comments that tell the code were to start and end the loop.
Sorry, I misunderstood your question. I'm hazarding a guess here, but I think you are using str_replace() wrong.
Using this: str_replace ('<!-- END '.$blockname.' -->', $blockCode.'<!-- END '.$blockname.' -->', $this->template);]
Looks for the string <!-- END '.$blockname.' -->, however then replaces it with "$blockCode.'<!-- END '.$blockname.' -->". I thought you were trying to delete them? Why not replace it with ""?
Here is how the str_replace() function is used:
str_replace("what you are replacing", "what to replace it with", "which variable is the replaced string in");
blu3t00th
05-02-2008, 03:48 AM
Ya I tried
(In 2 str_replaces)
$the->template = strreplace(Start comment, 'DATA', the->template)
$the->templae = strreplace(End comment, '', the->template)
And then it wouldnt replace, it seemd to be getting rid of the tags befor I could replace the data :/ and showed a blank page
If I understand, are you trying to remove the <!-- and -->, and the data (which you want inserted) will be placed in between?
blu3t00th
05-02-2008, 03:56 AM
Yep,
eg.
<!-- START Menu --> <- WANTED REMOVED AFTER DATA REPLACED (Not working atm)
<li><a href="{Menu.Linkto}">{Menu.Link}</a></li> <- THIS IS BEING LOOPED AS IT SHOULD (Working)
<!-- END Menu --> <- WANTED REMOVED AFTER DATA REPLACED (Not working atm)
<!-- START tagname --> <- REMOVE
DATA <- INSERT DATA
<!-- START tagname --> <- REMOVE
Then, I would suggest - keep it simple. Break your process down into three separate str_replace()s.
1. Replace the data first. using a separate str_replace();
2. Replace the <!--... using str_replace("<!--...","",...);
3. Replace the -->... using str_replace("-->...","",...);
(Ellipsies just means et cetera).
So, replacing your data would be something like:
str_replace("{Menu.Linkto}", $some_var, $subject);
Replacing the tags would be like:
str_replace("<!-- START tagname -->", "", $subject);
str_replace("<!-- END tagname -->", "", $subject);
Just, the replaced strings will by dynamic, not static.
blu3t00th
05-02-2008, 04:03 AM
So your saying something like this?
$this->template = str_replace ('<!-- END '.$blockname.' -->', $blockCode.'<!-- END '.$blockname.' -->', $this->template);
$this->template = str_replace ('<!-- END '.$blockname.' -->', '', $this->template);
$this->template = str_replace ('<!-- START '.$blockname.' -->', '', $this->template);
I am not understanding this snippet of code:
$this->template = str_replace ('<!-- END '.$blockname.' -->', $blockCode.'<!-- END '.$blockname.' -->', $this->template);
I thought, the only thing you were trying to replace (for example) {Menu.Linkto}. Why do you have <!--END and --> in both the search string and the replace string.
tomws
05-02-2008, 04:37 PM
...
Why do you have <!--END and --> in both the search string and the replace string.
I think you have it there. Should be something like:
// format str_replace($replaceThis,$withThis,$inthis)
$this->template = str_replace ('<!-- END '.$blockname.' -->', $blockCode, $this->template);
// same for START
The comments are still in the parsed source because the comments are still in the replace string.
Why are you using START and END anyway? Why not just use <!-- Menu -->?
$this->template = str_replace('<!-- '. $blockname .' -->', $blockCode, $this->template);
aedrin
05-02-2008, 08:28 PM
Probably because he has content that needs to be replaced:
<!-- START Menu --> <- WANTED REMOVED AFTER DATA REPLACED (Not working atm)
<li><a href="{Menu.Linkto}">{Menu.Link}</a></li> <- THIS IS BEING LOOPED AS IT SHOULD (Working)
<!-- END Menu --> <- WANTED REMOVED AFTER DATA REPLACED (Not working atm)
This shouldn't be that hard. You simply use preg_replace_callback(), use 1 regular expression to search for the blocks. That's all.
blu3t00th
05-02-2008, 08:40 PM
None of these suggestions seem to be working..
--
Idea
$this->template = str_replace ('<!-- END '.$blockname.' -->', $blockCode, $this->template);
$this->template = str_replace ('<!-- START '.$blockname.' -->', $blockCode, $this->template);
Does not loop, and displays double of the first entry in the array (The "Home" link)
--
Idea
$this->template = str_replace ('<!-- END '.$blockname.' -->', $blockCode.'<!-- END '.$blockname.' -->', $this->template);
$this->template = str_replace ('<!-- END '.$blockname.' -->', '', $this->template);
$this->template = str_replace ('<!-- START '.$blockname.' -->', '', $this->template);
Once again does not loop and only displays the first entry in the array (The "Home" link)
--
The part about using
<!-- START xxxxxx -->
<!-- END xxxxxx -->
Is to show were the template class should loop
--
This function finds and replacing the variables inside the loop
foreach ($tags as $tag => $data) {
$blockCode = str_replace ("{".$blockname.".".$tag."}", $data, $blockCode);
}
This inserts the replaced viables
$this->template = str_replace ('<!-- END '.$blockname.' -->', $blockCode.'<!-- END '.$blockname.' -->', $this->template);
The problem is if I get rid of the "<!-- START/END xxxxxx -->" in the above in any sort of way, it will just show the first entry because, for some reason it is removing the "<!-- START/END xxxxxx -->" before it runs the loop, therefore, not looping and only displaying the first entry in the array (because the comment is not there to signify were to do the loop)
--
Hopefully Im Making sence here...
aedrin
05-02-2008, 09:00 PM
The problem is already understood. The issue is that your solution and the ones provided by others are not effective.
You have a very simple problem. A simple template concept. One which is much like HTML, where you have a start tag, an end tag and content in between. You want to replace such content for each occurance of an item.
The html comments are getting a bit in the way of clean syntax. So say that I have this:
{block}repeat this code 5 times{/block}
All you need is this:
$data = '{block}repeat this code 5 times{/block}';
function repeatBlockFive($dataIn) {
$dataOut = '';
for ($i = 0; $i < 5; $i++) {
$dataOut .= $dataIn;
}
return $dataOut;
}
$result = preg_replace_callback('#{block}([^{]+){\/block}#', 'repeatBlockFive', $data);
This should be a good starting point.
blu3t00th
05-02-2008, 09:09 PM
But I want it like (block)repeat data x times while replacing this viable for x times(/block)
Your way is confusing me, what if I made a function like this? How would I use it, everywere I seem to insert it, it will show a blank page
function remove_block($blockName){
preg_match ('#<!-- START ' . $blockName . ' -->([^*]+)<!-- END ' . $blockName . ' -->#', $this->page, $resultCode);
@$this->template = str_replace($resultCode[0], '', $this->template);
}
aedrin
05-02-2008, 10:26 PM
But I want it like (block)repeat data x times while replacing this viable for x times(/block)
That's what I gave you.
Well, okay. I didn't quite chew your food for you. Like I said, I gave you a starting point on how to implement it. It obviously won't work in its current form according to your requirements. But you should have enough information to figure it out.
Your way is confusing me
If my way is confusing, then maybe you shouldn't attempt this. And instead look for a prebuilt solution.
It's a very simple concept.
How would I use it, everywere I seem to insert it, it will show a blank page
If something doesn't work, it doesn't mean the solution is bad.
blu3t00th
05-02-2008, 10:29 PM
That's what I gave you.
Well, okay. I didn't quite chew your food for you. Like I said, I gave you a starting point on how to implement it. It obviously won't work in its current form according to your requirements. But you should have enough information to figure it out.
If my way is confusing, then maybe you shouldn't attempt this. And instead look for a prebuilt solution.
It's a very simple concept.
If something doesn't work, it doesn't mean the solution is bad.
Ok Ill try messing around with it a bit, basicly your saying I should just rewrite that whole loop thing? and what does "preg_replace_callback" do? and why should I not use "str_replace" in the function you gave me instead? I heard its faster thats all :S
Edit: Used php.net for "preg_replace_callback" and it seems the same as "str_replace", what do you think would be better?
Edit 2: Hmm after more looking it seems that the use for it is so you can put in a function for the second value (find,function replace,result), am I on the right lines?
Inigoesdr
05-02-2008, 10:39 PM
Edit: Used php.net for "preg_replace_callback" and it seems the same as "str_replace", what do you think would be better?
Unless you need regular expressions(wildcards, ranges, etc.) there is no need to use the preg_* functions.
Edit 2: Hmm after more looking it seems that the use for it is so you can put in a function for the second value (find,function replace,result), am I on the right lines?
Yes, preg_replace_callback() (http://php.net/preg_replace_callback) is used to execute a function on the result of the regular expression.
blu3t00th
05-02-2008, 10:45 PM
Hmm, Im still confused, will I still need to input the data with arrays and use this still? but with the new function and scrap the old one?
while(list($key, $value) = each($Menu)){ //Replaces results and loops
$template->assign_block_vars("Menu", array("Link" => $value[0],
"Linkto" => $value[1]));
}
Inigoesdr
05-03-2008, 04:51 PM
You would pass an array to your block var assign function, yes. It would probably decide through some logic to use the repeating block or not, and you would call that function aedrin gave you in that case.
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.