Hi there. I've written a small script that I use privately on my server as a file upload and temporary storage bin. In other words, I open this page, upload any files I want, and then be able to download them from another location.
It beats E-mail, and I can see the files from any machine.

Anyway, I wanted to add a quick "log in" for it. Just a password, not a username/pass combo. There are no users, just a password.

I've got all that working just fine, but here is the issue. When the page loads, I want everything to display on the page, but have a couple features disabled if they are not logged in. They can see the files and what not, they just can't add more or delete them.

To accomplish this, I created a function which returns plain text that I use later in the page when showing forms and such.

For one example, inside the submit button you can use the keyword "disabled" and your button will not work. So basically all I did was say (in the function) IF logged in, then $status = "disabled". Down in my form I simply type it out with that variable:
echo "<input $status type=........". If they are logged in, $status is just a blank, if not logged in, it equals "disabled". It's pretty simple and dirty.

Here is the main problem, I use a while loop to display the contents of the temp folder. Each time it loops, I show one of the files with a little delete button next to it. Of course, if they aren't logged in, I want that button disabled. Only form elements have the "disabled" keyword, so I can't use the same tactic on an <img> or <a> tag (I don't think).
To accomplish the same basic goal as above, I set my $status variable to the onClick event. onClick for the <img> tag is where I use javascript to eventually delete the file. So I figure, hey, why not just set $status to the whole onClick text? So in other words, my original <img> might be:

echo "<img src=\"bla\" onClick=\"del_file($file);\" />";

Notice there is a variable used in the onClick event, this is part of the while loop, it tells jscript what the file name so it can be deleted. I had the brilliant idea that up in my function I could do the same as before. When logged in I would just set $status to the entire onClick text, and if not logged in, leave it blank. This way the <img> tag would have no click event and thus files couldn't be deleted.

I thought there were two ways to do this, I would make onClick to a string like:

$status = "  onClick=\"del_file($file);\"  ";

This doesn't work, because it tries to evaluate the $file variable, and it can't because this is in a function and my while loop hasn't even run yet. So maybe I escape the variable:

$status = "  onClick=\"del_file(\$file);\"  ";

Then it doesn't get evaluated while setting the text.
In any case, the function works, and the loop works, but what doesn't work is trying to get this text to appear in the PHP code and be evaluated properly with that $file variable. I tried just echoing the text:

echo "<img src=\"bla\" "  .  $status  .   " />";

This doesn't work because it won't evaluate the variable, it will literally send the text "$file" to the javascript function.
Then I thought eval() would work, this is what it's FOR anyway, right? To evaluate a string as php code?

echo "<img src=\"bla\" "  .  eval($status)  .   " />";

And therein lies my question, I can't get eval to work. And again it has to do with using the $file variable. When I create the string up in my function, $file is not even initialized yet, it can only be a string and not evaluated. But later on with eval() checks it, I just get errors. $file not initialized. Or it sends "$file" to javascript, or something else happens. I get parse error in the "eval'd" code, etc...

Here is another problem, I've been reading page after page about how to use eval, and in every example, whenever the strings are created, you know $string = "text to eval later", they always have their variables set first. Like:
$var1 = "joe";
$var2 = "bill";
$eval = "hey \$var1 and \$var2";
echo eval($eval);

Whatever it might be. In my case, I need to create the eval text, using variables, but the variables are not created yet, but they ARE created when I actually use the eval() function on the string. More like this:

$eval = "hey \$var1 and \$var2";

$var1 = "joe";
$var2 = "bill";
echo eval($eval);

If any of this makes sense at all, tell me what I'm missing here. All I want to do is turn the php text " onClick=\"del_file($file);\" " into a string that will work with eval(). Is it really that hard?
I suppose there are other ways to do this, I could just make two statements, and echo one if logged in and one if not, but then every time WHILE loops, I have to check if they are logged in, which wastes time. I can check just once, and set a variable to use in each loop, if possible. Is there some other way?

Thanks

    
    if($user) //user is logged in and validated
    {
    echo "<img src=\"bla\" onClick=\"del_file($file);\" />"; 
    }
    else
    {
    echo "<img src=\"bla\" />"; 
    }
    
    

    simple... although poorly validated since anyone looking at your JS could see the delete method and could do bad things...

    i would pass an id/filename to a delete.php page where you can again validate the user session and delete from there

      And remember the mantra: "If eval() is the answer, you're probably asking the wrong question." 😉

        The problem with that Scrup is that I am inside a while loop which is showing every file in the folder and styling it. In other words, if there are 50 files, I end up saying "if($logged)" 50 times which is a huge waste. It only needs to be checked once, and then go in to the while loop. This is why I thought, why not do that check once, and set the text I need to a variable:

        if($logged) then $text = "<img logged in text" ELSE "<img not logged in"
        while(loop through files and use variable $file)
        echo $text;

        I don't need to check if they are logged in every time the while loops. But I do need to use the $file variables every time it loops.

        I know the site isn't super secure, remember this is just a thing on my private server to throw files around, not really a public access thing. Also, the javascript doesn't delete anything, since jscript doesn't have access to your HDD like that. The Jscript simply fills in a hidden form which does send the delete action to a separate php file, and I can double check the login status.

        To NogDog, I know eval() is not well liked, but it seemed like the right choice insofar as answering the question: "how do I store a php string that uses variables to be displayed later on when the variables are created?"
        Is that the wrong question?
        I guess the right question is: "how do I switch a small piece of code to a different piece of code based on logged in status but maintain good performance?"

        Frankly, I'd like to get eval() to work for no other reason than it ticks me off and I want to solve it.

          I'm admittedly not entirely sure what you're trying to do: my mind is not ready to concentrate hard enough to work through all of this right now. 🙂

          It sort of sounds like you're trying to set up a piece of template text that you want to use later with dynamic values? If so, I would probably opt for some sort of place-holder that you would replace via str_replace() or preg_replace, e.g.:

          $text = "<p>foo [[replace_me]] bar</p>\n";
          
          $data = array('one', 'two', 'three');
          foreach($data as $num)
          {
             echo str_replace('[[replace_me]]', $num);
          }
          

            Yes that is about right. Here is what makes it weird, the "[replace_me]" part uses a variable (such as the $num in your example). So [replace_me] might say "this IS $num" or it might say nothing at all, perhaps it doesn't use the variable and maybe it does?
            In my specific situation, [replace_me] is either blank text "", or it is the onClick event which uses the variable from within the while loop "onClick="del_file($file);"".
            If I store this [replace_me] text in a variable, it has to contain the $file reference, even though $file isn't created until I enter the while loop. Here is how the logic of it works, paraphrased to follow it easy.

            <?php
            session_start();
            
            // This array is how I will store text based on their logged in status.
            $logged = array("text1" => "", "text2" => "", "text3" => "");
            
            // This function is called once per page load and sets the array text based on logged in status.
            // Essentially this is the "replace_me" text blocks that represent logged in or out status
            
            function logged_text() {
              if ($_SESSION['logged'] == "true") {
                $logged['text1'] = "onClick=\"del_file(\$file);\""; // Var means nothing here, but will later.
                $logged['text2'] = "a part that shows they are logged in";
                $logged['text3'] = "a part that shows they are logged in";
                return $logged;  
            } else { $logged['text1'] = ""; // Blank because I just have nothing to print there when logged off. $logged['text2'] = "a part that shows they are logged out"; $logged['text3'] = "a part that shows they are logged out"; return $logged; } // Call the function before drawing front end. $logged = logged_text(); echo "drawing a table or something, and then perhaps one of the $logged texts is a new row that shows them as logged out, like this"; echo "$logged['text2']"; echo "here is the rest of the table"; // If they are logged in, text2 might contain "<tr><td>Thou art logged in</td></tr>". // If they are logged out, text2 might contain nothing, or "Thou art logged out". // This works fine for plain text, but when using variables, it gets hairy. // Here I enter a loop that reads every file in the directory and makes a row to show it. while (false !==($file = readdir($dh))) { if (!is_dir("$dir/$file")) { // Alternate row colors $rowcolor = ($c &#37; 2) ? $color1 : $color2; // Show list of files including image for delete button. // I need to display or not display that IMG based on logged in status. // However, I can't store it as text because it uses a variable local to this loop echo "<div style=\"background-color:$rowcolor;\"><div id=\"sup_filename\"> <a href=\"$dir$file\">$file</a></div> <div><img align=\"center\" alt=\"delete\" src=\"sup_del.png\""; echo eval($logged['text1']); echo "/></div></div>"; $c++; } } ?>

            Notice that the one string of text I'd like to turn on and off is that img, or specifically just the onClick event that would go there. I store the text up in the function, including the variable reference. And then I want to eval() that string. It seems to me that is exactly what eval is for.
            I do NOT want to check for logged in status every time the while loop grabs a new file, that is wholly redundant and useless. Therefore, I just want to check once, storing the proper code in a var and using it through each loop. I just can't seem to do it because of that darn variable!

            I hope that makes it more clear, but I dunno, I'm pretty confused myself!
            Thanks for the help.

              So to use my suggestion:

              function logged_text()
              {
                 $logged = array();
                 if ($_SESSION['logged'] == "true")
                 {
                    $logged['text1'] = "onClick=\"del_file([[FILE]]);\""; // Var means nothing here, but will later.
                    $logged['text2'] = "a part that shows they are logged in";
                    $logged['text3'] = "a part that shows they are logged in";
                    return $logged;
                 } 
                 else
                 {
                    $logged['text1'] = ""; // Blank because I just have nothing to print there when logged off.
                    $logged['text2'] = "a part that shows they are logged out";
                    $logged['text3'] = "a part that shows they are logged out";
                    return $logged;
                 }
              }
              

              And to use it:

              $logged = logged_text();
              
              while (false !== ($file = readdir($dh)))
              {
                 if (!is_dir("$dir/$file"))
                 {
                    // Alternate row colors
                    $rowcolor = ($c != 2) ? $color1 : $color2; // not sure what comparison operator is here?
              
                // Show list of files including image for delete button.
                echo "<div style=\"background-color:$rowcolor;\"><div id=\"sup_filename\">
              <a href=\"$dir$file\">$file</a></div>
              <div><img align=\"center\" alt=\"delete\" src=\"sup_del.png\"";
                echo str_replace('[[FILE]]', $file, $logged['text1']);
                echo "/></div></div>";
                $c++;
                 }
              }
              

                PS: If you really, really want to use eval(), its argument must be a complete PHP command that can stand by itself, not part of a command.

                $var = 'fubar';
                
                // works
                eval('echo <p>$fubar</p>';);
                
                // does NOT work:
                echo "<p>" . eval('$fubar') . "</p>";
                

                  I see what you're saying and I think that would work too. But it's too late 😉
                  Instead of just have the IMG in there, I went ahead and put the whole darn form in there, using a <button> with the IMG on it. This way I can toggle the "disabled" keyword inside the button and don't have to worry about the variable.

                  I could have done it this way before but thought that basically making an entire new form for every file to have a delete button, was a bit much. Would be better (I think) to have one form which is hidden, and then use javascript to put the right values into it and submit it.

                  If I want to go back to having one form instead of dozens, I'll use your suggestion, it makes sense.

                  P.S. I did try converting the string to a "full" command to use in eval. You know like saying

                  'echo "onClick=\"del_file($file);\"'

                  or whatever it would be, but still had parse errors. So screw it, I hope I don't have to use eval ever again, it's really a touchy function.

                  Thanks

                    I hope I don't have to use eval ever again, it's really a touchy function.

                    One reason for the mantra NogDog quoted.

                      Write a Reply...