Solved

Searching within file and str_replace()ing

Posted on 2004-10-28
320 Views
Last Modified: 2009-12-16
Hi Guys,

I am trying to work with a very simple templat ing kind of system which

1:fopen() a local .tpl file
2:str_replace <!--links1--> with some content
3:output

I can do the above without a problem, but I would like to extend the above and need your help there...becaues I think I will need some RegEx...and I suck at RegEx's.Plus I would like your input as this is something i have not done till now, but you more experenced guys might have....

1: Basically, I want to be able to specify how many records to fetch like so
<!--links1 25-->

then i can query the db accordingly to fetch 25 records....


2: I would like to have categories like so:

***show_options.tpl***
<html>
<body>
And here are some cartoons:
<!--cartoons 25-->
<br><br>
Or if  you prefer full movies:
<!--movies 15-->
</body>
</html>

so I guess I will need a regex that can check the file and see if categories exist according to the array, eg:

$categories=array("cartoons","movies","jokes","pictures","yummy","mickey","donald","batman");

if <!--cartoons 23--> is found then
$found_cats=array
(
cartoons =>"23" // the number of cartoons to query the db
)


These are just my ideas....I would appreciate any comments you have or if you have any arguements why they are not good please tell me.
eg:
Do you think I will have a problem if the .tpl files are big? (eg: >= 90kb)
Regex will be too slow...
Mag, you're too ugly... :-)
etc


Thanks,
Mag
0
Question by:mag1c1an
    7 Comments
     
    LVL 49

    Expert Comment

    by:Roonaan
    Offcourse i could be wrong about this, but isn't the most important reason for using templates to separate php from html/ processing from output.

    Therefor it would be inappropriate to have templates tell you processing how to act. In my opinion not templates should say the number of elements it wants to be read from database, but configuration (static or session based).

    If you would like to use your templates in such a way, please use plain php then; i.e.: use <?php tpl_get('links',25); ?> instead of <!--links 25-->.

    My 2cts.

    -r-

    0
     

    Expert Comment

    by:mkortleven
    First you need to get the ids and record counts, than getting the data and at last replace and display it.
    RegEx are extremely fast, if you code them correct ;-)

    Getting the ids and the record counts:

    $found = array();
    if (preg_match_all('#<!--\s*([^>\s])\s+(\d+)\s*-->#', $fileContents, $matches, PREG_SET_ORDER)) {
        foreach ($matches as $match) {
            $found[$match[0]] = $match[1];
        }
    }

    Get the data:

    $data = array();
    foreach ($found as $key => $count) {
        $data[$key] = /* YOUR data as HTML string for $key with $count rows */
    }

    Replace the "tags":

    // create RegEx tags
    $regExTags = array();
    foreach ($found as $key => $count) {
        $regExTags[] = sprintf(
                '#<!--\s*%s\s+%d\s*-->#',
                preg_quote($key, '#'),
                $count
            );
    }
    $fileContents = preg_replace($regExTags, $data, $fileContents);


    Is this what you mean?

    Marc
    0
     
    LVL 2

    Author Comment

    by:mag1c1an
    Hi Roonaan,
    Thanks for replying.

    I do need the template file to tell the php file what records to get etc as the end user will be makeing his own .tpl files and specifying how many records he wants returned from which category.

    can you explain a bit more on how to use this:
    <?php tpl_get('links',25); ?>


    ***

    Marc,
    Thanks for replying, what you wrote looks like total gibberish to me :-) but i'll take your word that RegEX's are fast if used correctly...I dont know any better.
    I'll run your code get back to ya.

    Cheers,
    Mag
    0
     
    LVL 2

    Author Comment

    by:mag1c1an
    Hi again Marc,

    Its now working..... below is how I tried testing it, where am I going wrong?

    *** start code ***

    <?php
    $fileContents=<<<blah
    <html>
    <body>
    And here are some cartoons:
    <!--cartoons 25-->
    <br><br>
    Or if  you prefer full movies:
    <!--movies 15-->
    </body>
    </html>
    blah;

    $found = array();
    if (preg_match_all('#<!--\s*([^>\s])\s+(\d+)\s*-->#', $fileContents, $matches, PREG_SET_ORDER)) {echo "in preg_match";
        foreach ($matches as $match) {
            $found[$match[0]] = $match[1];
                echo "in first foreach";
        }
    }

    //Get the data:

    $data = array();
    foreach ($found as $key => $count) {
        $data[$key] = "\$key was: $key and \$count was: $count";/* YOUR data as HTML string for $key with $count rows */
          echo "In second foreach() ".$key. " ".$count;
    }

    //Replace the "tags":

    // create RegEx tags
    $regExTags = array();
    foreach ($found as $key => $count) {
        $regExTags[] = sprintf(
                '#<!--\s*%s\s+%d\s*-->#',
                preg_quote($key, '#'),
                $count
            );
    }
    $fileContents = preg_replace($regExTags, $data, $fileContents);
    print_r($fileContents);
    ?>


    *** End code ***

    Thanks,
    Mag
    0
     
    LVL 2

    Author Comment

    by:mag1c1an
    Oops, I meant "not" working, it does not seem to be 'catching' any of the tags...

    -Mag
    0
     
    LVL 2

    Accepted Solution

    by:
    Try this,

    please input database parameters
      username, password and your database

    Template file -- template.tpl
    --------------------------------

    <html>
    <body>
    And here are some cartoons:
    <!--cartoons 2-->
    <br><br>
    Or if  you prefer full movies:
    <!--movies 5-->
    </body>
    </html>

    ---------------------------------
    assuming database tables

    create table movies( links varchar(100) );
          and insert some links like

    insert into movies values("link1.html");
    insert into movies values("link2.html");
    insert into movies values("link3.html");

    create table cartoons( links varchar(100) );
          and insert some links like

    insert into cartoons values("link1.html");
    insert into cartoons values("link2.html");
    insert into cartoons values("link3.html");

    now check it out
    -------------------

    <?php
    $content = join("",file("template.tpl"));  // check template.tpl path

    $categories=array("cartoons","movies","jokes","pictures","yummy","mickey","donald","batman");

    foreach ($categories as $value){
          $pattern = "/<!--".$value." (\d+)?-->/";
          if (preg_match($pattern,$content) == 1)
                preg_match($pattern,$content,$matches[]);
    }

    // connect to database
    $dbc = mysql_connect("localhost", "user", "password") or die("Could not connect: " . mysql_error());
    mysql_select_db($database_name, $dbc);  

    foreach ($matches as $key =>$value){
          preg_match("/\w+/",$value[0],$res);
          $query = "select links from ".$res[0]." limit ".$value[1]."\n";

          $result = mysql_query($query);
          $count = 0;
          while ($rows = mysql_fetch_array($result))
          {
                $links["$res[0]"][$count] = $rows['links'];  // database links accorting to category
                $count++;
          }
    }

    $urls = "";
    $head = "";
    $index = 0;

    foreach ($links as $key => $cat){
          $head = "<b>".$key."</b><br>";
          foreach ($cat as $key => $value){
                $urls .= "<a href='$value'>".$value."</a><br>";
          }
          $content = str_replace($matches[$index][0],$head.$urls,$content);
          $index++;
          $urls = "";
    }

    echo $content;
    ?>
    0
     
    LVL 2

    Author Comment

    by:mag1c1an
    Hi,
    Thanks for replying, your solution was not *exactly* what I was looking for but thankfully I was able to modify it to my needs, I just needed your regex's which i didnt know how to write. So since your solution helped me solve my problem and I used the code from your solution...full points to you!

    Thanks,
    Mag
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone. Privacy Policy Terms of Use

    Featured Post

    Course: JavaScript Coding - Massive 12-Part Bundle

    Regardless of your programming skill level, you'll go from basics to advanced concepts in a vast array of JavaScript subjects including Sammy.js, Agility.js, Ember.js, Node.js, jQuery, AJAX, Extjs, AngularJS, Knockout.js, and JSON.

    A colleague recently asked me about how to give his client a small part of the web site that could be completely under the client's control.  Since I have done this sort of thing before to add emergency banners to a web site, I decided I would creat…
    Foreword (July, 2015) Since I first wrote this article, years ago, a great many more people have begun using the internet.  They are coming online from every part of the globe, learning, reading, shopping and spending money at an ever-increasing ra…
    Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
    The viewer will learn how to count occurrences of each item in an array.

    875 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    13 Experts available now in Live!

    Get 1:1 Help Now