LFSW-PPF; LFSWorld Data, right here, right now.

Discussion in 'LFSW-PPF' started by Anarchi-h, Jul 16, 2005.

  1. Anarchi-h

    Anarchi-h New Member

    Hi paXton;
    LFS-World will only let you get an entire PB list for a driver; it doesn't take the track parameter, hence unless I emulated it in the provider (which I don't) then LFSWPPF doesn't support it either.
    You'll have to either modify the pb provider to emulate this support, or an easier alternative (if you don't already know the ppf architecture) would be to filter teh pbs in a loop.

    As for the caching, LFSW-PPF will take care of that for requests to the same provider with the same parameters (i.e. a request for PBs with racer set to 'Anarchi-h'), but simply can't take care of requests to the same provider with different parameters (a different racer for instance). This is because PPF can not predict what data you are going to want, and hence can't cache it before you request it.
    The best way to solve this is a 'cyclic' request mechanism. This is a small wrapper that takes a list of params, and cycles through them, one per request. It caches the one from that request. If the pb requested is not the one that was just cached, you have to fetch an old cache entry for that pb so that you can display it. This means you must also 'prefetch' your entire list before going public, else you will still encounter lfsworld tarpit errors until the cyclic cache has completed at least one cycle of the list.

    That sounds a lot more complex than it is, but it is an unfortunate side effect of the tarpit that complicates things far beyond what they should be.

    P.S; Sorry for the slow response, I've been a bit pre-occupied with a newly aquired laptop like a kid with a new toy :p
     
  2. paXton

    paXton New Member

    Hi Anarchi!

    Now I've run into other Problems:

    Cause of not stressing LFSW too much and requesting the whole PBs of our racing team with the worldrecords, i've rewritten my racerstats.php to cache the pbs in a local mysql-database.
    ever x min i run a update_db.php fetching the latest pbs and wrs to add them to the database.
    under some circumstances it happend yesterday, that the update_db.php has added the worldrecord-times as the PBs of the first driver of our team.
    after checking my php-scripts, i have the only idea that this could only happen, if the "$LFSWorld->getParsed($pbprov, array('racer'=>$teamMember ))" returned the values from a previusly executed "$LFSWorld->getParsed($wrprov)"
    i attach the php, so you can check my script too.
    i've cleared the db 5 min ago, and now every thing seems to be ok, but i'll watch out,if the bug happens again.
    but these scripts are my first ones in php, and im not sure, if its not a error from me.


    here is the update.php:
    PHP:
    ini_set('include_path''/www/htdocs/v152026/local/PEAR' PATH_SEPARATOR ini_get('include_path'));

    require_once(
    'config.php');
    require_once(
    'misc/error.php');
    require_once(
    'lfsworld/lfsworld.php');
    require_once(
    'lfsworld/providers/data-provider.php');
    require_once(
    'lfsworld/providers/pb.php');
    require_once(
    'lfsworld/providers/wr.php');
    require_once(
    'lfsworld/caches/lfsworldclbridge.php');

    //Setup the Cache_lite interface bridge object
    $cacheParams = array('cacheDir'=>CACHE_DIR'automaticSerialization'=>true);
    $fileCache = new LFSWorldCacheLiteBridge(new Cache_Lite($cacheParams));

    //Init the LFSWorld object
    $LFSWorld = new LFSWorld($fileCache$fileCache);

    //Init a provider Object.
    $pbprov = new LFSWorldPersonalBests($cacheParams); //Uses shared Tarpit timer with PST
    $wrprov = new LFSWorldWorldRecords($cacheParams); //Uses shared Tarpit timer with PST

    $conn mysql_pconnect('localhost'username,pass);
    if (!
    mysql_select_db(dbname$conn)) die('Cannot select DB.');

    echo 
    "updating worldrecords ... ";

    $wrs $LFSWorld->getParsed($wrprov);
    if(
    is_a($wrs'Error'))
        die(
    $wrs->getMessage());  

    foreach(
    $wrs as $wr) {

        
    $update "UPDATE lfs_worldrecords SET ";
        
    $where "WHERE track='".$wr['track']."' AND car='".$wr['car']."';";
            
        
    $set "time='".$wr['time']."',";
        
    $set $set."flags='".$wr['flags']."',";
        
    $set $set."racer='".$wr['racer']."' ";

        
    $query $update.$set.$where;

        
    $result mysql_query($query) OR
            die(
    "Query: <pre>".$query."</pre>\n".
                
    "Antwort: ".mysql_error());
            
        
    preg_match(
            
    "/^[^0-9]+([0-9]+)[^0-9]+([0-9]+)[^0-9]+([0-9]+).*$/",
            
    mysql_info(),
            
    $arr);
                
        if( 
    $arr[1] == // a number of matched rows is 0
        
    {
            
              
    $into "INTO lfs_worldrecords (";
            
    $values " VALUES (";
        
            
    $into   $into."track,";
            
    $values $values."'".$wr['track']."',";

            
    $into   $into."car,";
            
    $values $values."'".$wr['car']."',";

            
    $into   $into."time,";
            
    $values $values."'".$wr['time']."',";

            
    $into   $into."flags,";
            
    $values $values."'".$wr['flags']."',";

            
    $into   $into."racer,";
            
    $values $values."'".$wr['racer']."',";

            
    $into   $into."modified)";
            
    $values $values."'0');";

            
    $query ="INSERT ".$into.$values;

            
    $result mysql_query($query) OR
                die(
    "Query: <pre>".$query."</pre>\n".
                    
    "Antwort: ".mysql_error());
        }
    }
    echo 
    "done\n";

    foreach(
    $theTeam as $teamMember) {
        echo 
    "updating " $teamMember " ... ";

        
    sleep(5);

        
    $pbs $LFSWorld->getParsed($pbprov, array('racer'=>$teamMember ));

        if(
    is_a($pbs'Error'))
            die(
    $pbs->getMessage());  
            
        foreach(
    $pbs as $pb) {

            
    $update "UPDATE lfs_racerstats SET ";
            
            
    $set "time='".$pb['time']."',";
            
    $set $set."laps='".$pb['laps']."' ";

            
    $where "WHERE racer='".$teamMember."' AND track='".$pb['track']."' AND car='".$pb['car']."';";

            
    $query $update.$set.$where;

            
    $result mysql_query($query) OR
                die(
    "Query: <pre>".$query."</pre>\n".
                    
    "Antwort: ".mysql_error());

            
    preg_match(
                
    "/^[^0-9]+([0-9]+)[^0-9]+([0-9]+)[^0-9]+([0-9]+).*$/",
                
    mysql_info(),
                
    $arr);
                
            if( 
    $arr[1] == // a number of matched rows is 0
            
    {
            
                  
    $into "INTO lfs_racerstats (";
                
    $values "VALUES (";
        
                
    $into   $into."racer,";
                
    $values $values."'".$teamMember."',";

                
    $into   $into."track,";
                
    $values $values."'".$pb['track']."',";

                
    $into   $into."car,";
                
    $values $values."'".$pb['car']."',";

                
    $into   $into."time,";
                
    $values $values."'".$pb['time']."',";

                
    $into   $into."laps,";
                
    $values $values."'".$pb['laps']."',";

                
    $into   $into."modified) ";
                
    $values $values."'0');";

                
    $query ="INSERT ".$into.$values;

                
    $result mysql_query($query) OR
                    die(
    "Query: <pre>".$query."</pre>\n".
                        
    "Antwort: ".mysql_error());

            }
        }
        echo 
    "done\n";        
    }
    besides you can think over this, and i try to understand the structure of lfsw-ppf.

    perhaps you have an idea, which helps me, or an improvment sugestion for my php-script.

    Ciao... Pascal
    PS: Sorry for my bad english. I hope you understand what i mean.
     
  3. Ian.H

    Ian.H Administrator Staff Member

    pax..

    Not sure as to the error you're posting about as I don't know the code off the top of my head but one part of your code really stands out to me.. the preg_match() call chcking for whether the DB was updated or not. A much simpler / cleaner method, unless I'm reading something wrong would be to use the mysql_affected_rows() function, for example:

    PHP:
    $ret mysql_query($query);
    if (
    $ret) {
      if (
    mysql_affected_rows() == 0) {
        
    // Do insert code here...
      
    }
    } else {
      die(
    '<pre>Query: ' $query "</pre>\nAntwort: " mysql_error());
    }

    I guess also, the actual query part could be more simple too using concat char:

    PHP:
    $query("
      INSERT INTO lfs_racerstats
            (
                racer,
                track,
                car,
                times,
                laps,
                modified
            ) VALUES (
                " 
    mysql_escape_string($teamMember) . ",
                " 
    mysql_escape_string($pb['track']) . ",
                " 
    mysql_escape_string($pb['car']) . ",
                " 
    mysql_escape_string($pb['times']) . ",
                " 
    mysql_escape_string($pb['laps']) . ",
                0
            )
    "
    );

    $ret mysql_query($query);
    (assuming track / car etc are string values not ints).


    Nothing wrong with the method you've used for this, but thought the above might be easier to read / maintain :)

    The preg_match() call however, if used too often can slowly reduce performance of a site as regex is quite resource intensive.. although you may never notice it.. I guess it's just something I always think about now.. although didn't when I first started with PHP.. but we live and learn :)

    Hope some of this info is useful, even if it doesn't solve your problem.



    Regards,

    Ian


    EDIT: Just to clarify the query stuff above.. the part before the VALUES() section in the SQL statement is quite important.. I'd personally try and get into the habit of specifying fieldnames as I have here. The reason's simple.. if for some reason you decide you want to add another column inbetween say, track and car, or perhaps swap the column position of laps and time.. the way you have it you'll need to change some extra code to so that your data is stored in the correct relative column.. by specifying the column name beforehand as per my code, you can add / remove and move columns around with no problem at all as they'll know where to go. The only time you'll then need to make any further code edits is if you actually rename the column.. but this is unavoidable.. but it'll certainly be the most reliable method for all future code. I never used to specify them either, until my code slowly started to go wrong.. never had a problem since I adopted this method :)

    Same goes for if you use phpMyAdmin for managing your DB.. if you export any data, always tick the checkbox for 'Extended Inserts' incase you make any changes to your tables but want to import backup data to fill in what you can :)
     
    Last edited: Jan 2, 2006
  4. paXton

    paXton New Member

    hello Ian,

    thank you for the improvements for my code.
    first i tried to change the building of the query string to your method, but i get this error:
    Code:
    Fatal error:  Call to undefined function:  () in /www/htdocs/.../update.php on line 36
    this is the line where the "$query(" startet.
    PHP:
    $query("
            UPDATE lfs_worldrecords SET
                time=" 
    mysql_escape_string($wr['time']) . ",
                flags=" 
    mysql_escape_string($wr['flags']) . ",
                racer=" 
    mysql_escape_string($wr['racer']) . "
            WHERE
                    track=" 
    mysql_escape_string($wr['track']) . "
                AND
                    car=" 
    mysql_escape_string($wr['car']) . "
            "
    );
    the preg_match() code is from php.net out of the user comments in the documentation. If the mysql_affected_rows() does really the same and fit my needs, i will use this.

    Ciao... Pascal
     
  5. Ian.H

    Ian.H Administrator Staff Member

    Ahh sorry sir.. I'm guessing you probably have an older version of PHP (can't remembr off hand when this function was introduced).

    For simplicity, either at the top of that script, or a script you include, create a function.. something like 'escape_sql()':


    PHP:
    function escape_sql($str) {
      return 
    addslashes(stripslashes($str));
    }

    Nothing fancy, but will escape certain chars (such as \' and \" etc) to help prevent SQL injection attacks and other innocent issues. Always follow a rule that user submitted data can't be trusted (in this case, rather than a user filling out a form, you're retrieving it from another server.. but same rule applies :) ).

    The you can replace the mysql_escape_string($wr['time']) for example with escape_sql($wr['time']) and it should do pretty much the same thing.

    For more info, check the mysql_escape_string() function at the php.net manual as it should at least let you know for sure then whether it's your PHP version that caused the unknown function error :)



    Regards,

    Ian
     
  6. paXton

    paXton New Member

    the problem is not the mysql_escape_string(), but the "$query()" !
    i changed the code like this and it works:
    PHP:
            $query="
                INSERT INTO lfs_worldrecords
                    (
                        track,
                        car,
                        time,
                        flags,
                        racer,
                        modified
                    ) VALUES (
                        '" 
    mysql_escape_string($wr['track']) . "',
                        '" 
    mysql_escape_string($wr['car']) . "',
                        '" 
    mysql_escape_string($wr['time']) . "',
                        '" 
    mysql_escape_string($wr['flags']) . "',
                        '" 
    mysql_escape_string($wr['racer']) . "',
                        0
                    )
                "
    ;
    although i needed to add >'< around the data to not get a sql error.

    Pascal aka paXton
     
  7. Ian.H

    Ian.H Administrator Staff Member

    Oops! Sorry pax.. I forgot the single quotes :-[ but glad you managed to fix it quick enough.. definitely looks a lot more readable to me :)



    Regards,

    Ian
     
  8. Anarchi-h

    Anarchi-h New Member

    Hmmm, can't see where values might have crossed over within LFSWorld, but I'm going to run some tests over here when I can to try and see if I can find one.
    Since your queries are independant asides from sharing an LFSWorld object and the cache, it must lie somewhere within PPF.

    I'll look in to your problem and get back to you. :)
     
  9. paXton

    paXton New Member

    But why does the $query("text") not work?
    PHP:
    $query("text"); // works for you
    $query="text"//works for me
    paXton
     
  10. Ian.H

    Ian.H Administrator Staff Member

    Ahhh.. sorry once again pax.. it was completely my error and should have been $query = " all the time :-[ I guess it's left from coding habits with common code I use. I wrote an SQL wrapper a long time ago and 99% of my SQL statements look something like:

    PHP:
    $ret $mysql->query("
      INSERT INTO .............
    "
    );
    but the way I had it in the example that failed for you, it'd be trying to use a function called whatever is stored in $query (and at that point, nothing is). This allows you to call dynamic functions, such as:

    PHP:
    if (in_array($make$cars)) {
      
    $something get_$make_details();
    where $make could be say, Ford or Vauxhall.. and that you have 'get_ford_details()' and 'get_vauxhall_details()' functions already written etc. Lots of goodies in PHP, some kinda confusing, but hope this makes some sense :)



    Regards,

    Ian
     
  11. Anarchi-h

    Anarchi-h New Member

    Sorry to correct your correction Ian, but you must build the function name before trying to call it. PHP can't cope with that syntax because it isn't expecting a variable in a literal function name, and even if it was, the underscore character is valid in a variable name so it would see $make_details, not $make :)

    PHP:
    $func "get_{$make}_details";
    $something $func();
    Paxton; something which I forgot to mention earlier is that for your inserts, you may want to use the multiple insertion syntax. You keep the same query as you have, but instead of just 1 set of values, you have multiple sets of values separated by a comma.

    Code:
    INSERT INTO table (field1, field2, field3) VALUES ('entry11', entry12', entry13'),
    ('entry21', 'entry22', 'entry23')'
    It may not make a big difference, but one query is better than 10 or 20.
     
  12. Ian.H

    Ian.H Administrator Staff Member

    uGH I'm going home! lol you're right of course, thanks for clearing that up A.. I didn't even manage to use concatenation.. god knows what I was thinking :-[ :)

    Good tip about the single / multiple queries too :thumb3d:



    Regards,

    Ian
     
  13. paXton

    paXton New Member

    yep, thanks. give me more performance. 8)

    now i've written my own parser for fetching the data (pb+wr) from lfsworld, which writes into a second DB.
    so i'm be able to compare the two DBs which should contain the same data. perhaps i could figure out, where the bug is.

    paXton... goes to bed now
     
  14. Bird

    Bird New Member

    Hello,

    I'm also a complete noob with php, but have some experience in coding otherwise.

    I d/l the files from the beginning of this post, and I believe if I could get them working locally, and play around/learn some things, then adding them to a web page will be less daunting.

    If you don't mind indulging me - as I understand it - I need Apache or iis, and php running, at which point the file examples will work ?

    Could you please explain a few basic things - such as these do programs run independently, from their own directories ?

    And, where exactly do I place the files from the start of this post in relation to this apps ?

    I guess I'm looking for step by step setup to at least get the examples running. If someone has the time to provide this, I'd be grateful.

    If it's too much to undertake, I understand that as well. I had to try.

    Thanks !

    bird

     
  15. jos belgium

    jos belgium New Member

    Is it possible to add a "small" getting-started guide in the first post?
    Maybe asks to much work or is it allready here somewhere, but would make some things simpler :).

    I'm a noob concerning php, but i have basic knowledge of programming. I want to make some statistical data pages for my team's website. I didn't get very far yet, because i'm stuck on some things and i don't know how to continue. I was searching on the website of lfsforum, and after a week found this topic.

    To keep it comfortable, i installed an evaluation version of the zend studio, with server included, so i have a server and php engine on my computer, so i can work on this.
    I copied the files to a subfolder of my server, i can see the files and folders in my browser, but i get the following error trying to open your examples:
    Code:
    Warning: main(HTTP/Request.php): failed to open stream: No such file or directory in ...\lfsstat\lfsworld\lfsworld.php on line 15
    
    Fatal error: main(): Failed opening required 'HTTP/Request.php' (include_path='.;c:\php4\pear') in ...\lfsstat\lfsworld\lfsworld.php on line 15
    [\code]
    
    i know this has something to do with the pear::http_request package, but i haven't figured out what to do.
     
  16. Anarchi-h

    Anarchi-h New Member

    Heya; sorry for the lack of responses; I've been busy with LFSW-PPF version 2 that WILL (Its in the process of being written now) have a 'getting started' guide.

    As for this version, if you just want a guide to getting the samples up and running, here we go...

    First thing you need to do is install the PEAR packages. If you have your own local php enabled webserver running, then go to your PHP directory and type 'go-pear'. Then restart, open up a command prompt and type 'pear install XXX' where XXX is the name of the packages you want to install. The ones you need to install are:

    Net_Sockets (not mentioned before now because it isn't directly used by PPF, but HTTP_Request needs it)
    Net_URL
    HTTP_Request
    Cache_lite

    and it's best to install them in that order too because of dependency checks.

    The 'go-pear' installer should have modified your php.ini to include the pear directory. If so, you should now be able to extract lfsw-ppf to anywhere within your document root, and the samples should work.

    If you don't have a local PHP server, things are a little more tricky, and I don't really have time to go in to details. However, in brief, you need to go to http://pear.php.net and download the above mentioned packages. Extract them all to the same directory. I.e. If you extract them to c:\pear , you should now have a directory structure like c:\pear\HTTP, c:\pear\Cache & c:\pear\net with a few files in there too.

    Now you need to upload this whole directory (so it is duplicated) to your remote server. Usually this is done by FTP. I recommend a directory that you can upload to beneath the document root, just as a matter of good practice.
    You need to know the absolute path to this directory though. It might look something like

    /home/user58697/www/pear/

    Next, you need to add the following line to each sample within PPF that you want to be able to run;

    PHP:
    ini_set('include_path'ini_get('include_path').':path_to_pear');
    Where the 'path_to_pear' bit contains your directory. If your remote host is a windows machine, you will need to change the : at the start of the string to a ;

    Now you can upload LFSW-PPF. The samples you modified should work.

    I think that is about it. Sorry I don't have time to be more detailed, but I want to get back to these version 2 docs so I can have them done asap. :)
     
  17. PaulC2K

    PaulC2K New Member

    Anyone still here?

    I installed this about a month ago, had problems and i've tried PM'ing Anarchi-H and i've added him to MSN but it seems he's vanished since late July and i was wondering if anyone could give me some assistance on installing the 4 packages.

    I installed it using go-PEAR which made things soooo much easier to install, however once inside its little admin like area its auto-installed the Cache_Lite package, however the others all error.
    I dont know if this is something go-PEAR does that a normal install doesnt have, but eitherway I dont have the other 3 packages installed so i cant go any further.
    I've been waiting in hope of a reply from A-H but it seems he's AWOL from LFS Forums so im hoping that maybe someone else here knows how to install these 3 packages manually??

    Short of that, i guess i could try another go-pear install and see if things change.
     

Share This Page