L
linus

  • May 29, 2005
  • Joined Jun 27, 2002
  • Sure thing:

    The first code segment sets the 'foo' cookie, which will expire in an hour. Then it sets another cookie with the time at which the value of the first cookie should no longer be used.

    Then, when you want to access the information stored in the 10-second cookie (probably in a different PHP file, or at least after the page is reloaded), do this:

    if (isset($_COOKIE['foo'])) { // check if the cookie is set
      if ($_COOKIE['expire_foo'] > time()) { // make sure we have not yet reached the time that the cookie was to expire
        echo 'Your foo is '.$COOKIE['foo'].'!';
      } else { // at least 10 seconds have passed since the cookie was set; do not use it and expire both cookies
        setcookie('foo', false);
        setcookie('expire_foo', false;
      }
    }
    
    • I have also run into this oddity of the cookie system. I don't know why it is so, but I can think of a way for you to get around it. Set the 10-second cookie with:

      $time = time();
      setcookie('foo', 'bar', $time+3600);
      setcookie('expire_foo', $time+10, $time+3600);
      

      ...then put this somewhere to check if it's been 10 seconds yet and expire it if so:

      if (isset($_COOKIE['expire_foo']) && $_COOKIE['expire_foo'] <= time()) {
        setcookie('foo', false);
        setcookie('expire_foo', false);
      }
      
      • The simplest way I can think of is to go through the directory and check each file, like so:

        // returns true on success, false if no file found
        function rename_anyExt($directory, $filename, $newFilename) {
          $dirPointer = opendir($directory);
          while ($item = readdir($dirPointer)) {
            $extStart = strrpos($item, '.'); // get start position of extension (if existant)
            $sansExt = $extStart ? substr($item, 0, $extStart) : $item; // get filename without extension
            if ($sansExt == $filename) { // if it's a match, rename the file and end this function
              $ext = $extStart ? substr($item, $extStart) : ''; // get extension, if existant
              rename($directory.$item, $directory.$newFilename.$ext);
              return true;
            }
          }
          return false; // no matching file was found
        }
        

        I didn't test this, let me know if there are issues. Also, this function will stop once it finds the first matching file, since it sounds like you're only expecting there to be one file.

        • I'm confused as to how the PHP script is interacting with your Flash file. If PHP is generating the page with the Flash file in it, you can add a query string to the URL of the Flash file, like so: www.something.com/folder/yourfile.swf?directoryname=foo

          I think this only works in the latest version of Flash.

          • Mrhappiness covered #4 in the last regex. %[a-z0-9]+[0-9]+[a-z0-9]+$%i would mean "at least one letter/number followed by at least one number followed by at least one letter/number." So his function should do it for you. However instead of using a regex to make sure the case is varied, like he does:

                //check mixture of of upper and lowercase letters
                if (preg_match('%[a-z]+%', $pass) ^ preg_match('%[A-Z]+%', $pass))
                    return false; 

            ...you can use simple string functions, which should be marginally faster:

              // check mixture of upper and lowercase letters
              if (
                ($pass == strtoupper($pass)) || // i.e. it's all uppercase
                ($pass == strtolower($pass)) // i.e. it's all lowercase
              )
                return false;
            
            • There are many PHP template scripts that have fancy ways to separate your "business code" from your "display code" (a common issue, and it sounds like this is what you want), but I usually just use PHP to do this, like so:

              Business code:

              $templateVars = array();
              // prepare DB connection
              $userRow = // retrieve the row
              $templateVars['username'] = $row['name'];
              $templateVars['email'] = $row['email'];
              
              ...
              

              Display code:

              <!-- insert fun table code for user profile page -->
              <tr>
                <td>Username:</td>
                <td><?php echo $templateVars['username'] ?></td>
              </tr>
              <tr>
                <td>Email:</td>
                <td><?php echo $templateVars['email'] ?></td>
              </tr>
              
              ...
              

              This is a very basic example obviously... note that I use an array to give the template variables a different scope from the variables in my business code so they don't get mixed up. In the non-example world (that I assume you're coding in 🙂), this is more easily done with a template class. I can give you the one I use if you want, or you can choose from the many many template classes available on the internet.

              But the point is this makes it easy to edit the page's HTML without having to look at the code for interacting with the database and such.

              Btw good job for thinking of this, when I was a newbie and wrote my first BB system, ALL the code went together. 🙂 Not that you're a newbie.

              • I think Bradgrafelman's implementation of pausing works like this:

                When the timer first starts, you insert the current time into the start_time field.

                Whenever it's paused, you calculate the time so far (current time minus the start_time field), add that to the value of the duration field, and put the result into duration. The first time it's paused, duration will be 0, but as it's paused again and again the duration will update.

                When it's unpaused, insert the current time into start_time.

                When it's finished, do the same thing, update the duration field to (current_time - start_time + duration), and you have the total time.

                • The expression you're using is badly crafted. First of all, the dot in the second half of the email address needs to be escaped (.) or it will mean "any character." But also .* will match any character any number of times, and will match as many as possible unless you tell it to not be greedy (by adding the U flag -- see PHP manual). Try using this expression:

                  /(\S+)@(\S+).(\S+)/

                  This will match:
                  - at least 1 non-space-character, followed by
                  - @, followed by
                  - at least 1 non-space-character, followed by
                  - . (dot), followed by
                  - at least 1 non-space-character.

                  I haven't tested it but it should match any email address, although it will also match invalid email addresses with non-ascii characters and such. Let me know what happens!

                  P.S. I found this handy reference:
                  http://www.wdvl.com/Authoring/Languages/Perl/PerlfortheWeb/perlintro2_table1.html

                  • I think it would help if you (1) added some comments to the code, and (2) told us exactly what's not working -- are you getting an error or is something unexpected happening?

                    • Originally posted by bradgrafelman
                      The only problem with Javascript would be that the current duration would be lost if the user refreshed or closed the window, which is exactly what Manijak was trying to prevent.

                      That's what the cookie's for 🙂

                      • mysql_num_rows() is the function you want, it'll tell you how many rows were returned. Your code can be as simple as this:

                        
                        $result = mysql_query(...etc...);
                        if (mysql_num_rows($result) => 5) {
                          // mischief is afoot
                        }
                        
                        

                        Mysql_fetch_array is used to retrieve the values of the fields, not the number of rows. It's always good PHP practise to use var_dump() on things to teach you about their structures (like the return value of the fetch_array function), and it's always good MySQL practise to take whatever query you're using and paste it into the mysql console or into PhpMyAdmin so you can see exactly what gets returned and how.

                        [As an aside, you could use fetch_array to find out how many rows were returned by doing the following:

                        $result = mysql_query(etc);
                        $rows = mysql_fetch_array($result);
                        if (count($rows) => 5) { // count the number of elements in the array
                          // bounced!
                        }
                        

                        ... but obviously that's a pretty roundabout way to do it.]

                        • There was an ALA article (http://www.alistapart.com/articles/hotlinking/) about preventing image hotlinking from other sites, but the thing is it fails if I tell my browser not to send the HTTP_REFERER header. You could add the condition that the header can't be blank, but (a) this isn't nice to people who disable it on principle, and (b) it doesn't solve the problem that it can theoretically be forged. I can't think of another way to do this; I think the internet is too free a system to manage this kind of restriction reliably. In Apache terms, the nature of the internet is deny,allow.

                          • Alternatively if you wanted to use Javascript, you could have a function that would call itself recursively using setTimeout() to call itself every minute. The function would add 1 to the elapsed time, and store (or update) the value in a cookie.

                            To implement pausing, you'd have a variable like isPaused, and the above function would only run if isPaused was false. The pause function would set isPaused to true, and the unpause function would set it to false and call the timer function.

                            • Through laziness I've never messed that much with sessions, but it is important to note that if you log someone in by putting their username and password in cookies, the credentials in the cookies should be checked against those in the database in every single script. Otherwise I can go into the members list (say), forge my username cookie to be anyone and my password cookie to be anything (so long as it's present) and I will be "logged in."

                              • If you wanted to use text links and Javascript, the easiest way would be just to make the script submit the form. Each link would have to (1) somehow get across whether to edit or delete and (2) submit the form. The simplest way I can think of at the moment is to do the beginning of your form like this:

                                
                                <form action="process_edit_del.php" method="post">
                                  <input type="hidden" name="action" value="" id="checkBoxAction" />
                                  <a href="javascript:submit('Edit');">Edit</a> |
                                  <a href="javascript:submit('Delete');">Delete</a>
                                
                                ...
                                
                                

                                ...and have your script like this:

                                
                                <script type="text/javascript">
                                function submit(action) {
                                  var actionRef = document.getElementById('checkBoxAction');
                                  actionRef.value = action;
                                  actionRef.form.submit();
                                }
                                </script>
                                
                                

                                I haven't tested this but I think it should work. What it does is use javascript set the value of a hidden field called 'action', and then submit the form. The contents of the $_POST array will be the same.

                                [edit: I don't know why there are spaces in the <a href="javascript:... part, but there shouldn't be. Forum bug.]

                                • If you're willing to have the "Edit" and "Delete" links be form submission buttons, it's easy and requires no Javascript. The page's HTML should look like this:

                                  
                                  <form action="process_checkbox_action.php" method="post">
                                    <input type="submit" name="action" value="Edit" />
                                    <input type="submit" name="action" value="Delete" />
                                  
                                  <!-- and for the loop... -->
                                    <input type="checkbox" name="checked[]" value="<?php echo $nameId ?>" /> <?php echo $name ?>
                                  <!-- end loop -->
                                  </form>
                                  
                                  

                                  The form gets submitted to process_checkbox_action.php (or whatever you want to call it 🙂), and $POST['checked'] will be an array of all the nameIDs that were checked, making it easy to work with them. $POST['action'] will either be 'Edit' or 'Delete', depending on which button was clicked. I hope this helps. If you need the Edit/Delete options to be links and not buttons, some javascript is required, but nothing too horrendous.

                                  • Why do you need the array_flip()s? This should work fine:

                                    $lines = file('tst.txt');
                                    $lines = array_reverse($lines);
                                    
                                    foreach ($lines as $line) {
                                       echo trim($line) . "<br />\n";
                                    }
                                    
                                    • How about just running a few queries like this:

                                      UPDATE music SET artist = 'Busta Rhymes' WHERE artist = 'Busta Rythmes';

                                      Unless there are a whole lot of different misspellings... but this would take care of most, if not all of them.

                                      • Here's my problem: I'm trying to match any image tag whose URI isn't absolute (i.e. doesn't begin with http://).

                                        <img src="[^http://]

                                        That won't work the way I want: it doesn't negate the string 'http://;' it negates either an h, t, p, :, or /. I thought this might work:

                                        <img src="[^(http://)]

                                        ...but paretheses are taken literally inside brackets, so that won't do what I want either.

                                        Any ideas? Thanks for your time...