tags:

views:

156

answers:

1

I am developing a links voting site, and I have this function, to check if the user already voted the link:

function  has_voted($user) 
    {
       try
        {
            $db = parent::getConnection();
            $query = "select id from votes where username = '$user' and article_id  = $this->id";
            $results = parent::execSQL($query);
            if($results->num_rows == 1) {
                return true;                 
            }
            else 
            {
                return false;
            }            
            parent::closeConnection($db);

        }
        catch(Exception $e){
            throw $e;
        }       
    }

And in the frontpage I display an image to vote with this line:

  <a href="/index.php?action=vote&amp;param=<?php echo $articles[$index]->getId(); ?>">
<img class="vote_button" src="assets/images/triangulo.png" />
</a>

What I want its to insert an "if" to display a different image if the user already voted, I tried this but it shows errors:

    <a href="/index.php?action=vote&amp;param=<?php echo $articles[$index]->getId(); ?>">
<?php if($articles[$index]->has_voted($articles[$index]->getUsername()) == true) 
{ ?><img src="assets/images/triangulo.png"/></a><?php } 
else 
{ ?><img class="vote_button"  src="assets/images/triangulo2.png" /></a><?php } ?>

+++Edit:

Schnalle,

Thanks for the analysis, this is what I did:

  • ok I took parent::closeConnection($db) out, thanks

  • I try to cut the catch statement also but I got this error: Parse error: syntax error, unexpected '}', expecting T_CATCH in /home/mexautos/public_html/kiubbo/data/article.php on line 155

  • I get the user name here, I dont know if its safe enough:

    function getUsername(){ return $this->username; }

    I tried this code to sanitize it:

    $query = sprintf("select id from votes where username = '$user' and article_id = $this->id", mysql_real_escape_string($user), mysql_real_escape_string($password));

    but I get this error for the mysql_real_escape lines:

Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: Access denied for user 'mexautos'@'localhost' (using password: NO) in /home/mexautos/public_html/kiubbo/data/article.php on line 145 Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: A link to the server could not be established in /home/mexautos/public_html/kiubbo/data/article.php on line 145 Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: Access denied for user 'mexautos'@'localhost' (using password: NO) in /home/mexautos/public_html/kiubbo/data/article.php on line 146 Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: A link to the server could not be established in /home/mexautos/public_html/kiubbo/data/article.php on line 146

  • I will close the tag outside once I fix this, I was not sure if it worked separately.

  • You are right I was getting the wrong variable. I changed to $_SESSION['user'] and it worked!

  • I understand what you say: instead of writing links with a loop just select them and write them down, I will check that to learn how to do it.

  • I use an id for this, let me implement it.

Thanks, CS

+9  A: 

What I want its to insert an "if" to display a different image if the user already voted, I tried this but it shows errors

errors? ah-ha! there may be a problem ... with the errors. my advice: shoo the errors away with a broom or loud noises, then your code may work.

if that doesn't help, try to ignore them. errors want your attention. that's why there are so many error messages and notices in PHP (and most other programming languages). notices are little baby errors, not yet dangerous, but when fully grown they can take down apps way bigger than they are.
fact: if you ignore them they tend to go away because they get bored.

but if you got some very consistent errors that still won't go away, there may be another tactic:

post indecent pictures of the errors on the internet, preferably on SO (SO is the programmers TMZ). errors are a proud and vain, so most of them are so ashamed they hide under a rock and cry until the whole thing is fogotten. do this only if you have no heart.

update:

i did't want to be unfriendly or impolite here, it's just that there are a lot of things wrong with your code, and i made fun of the fact you told us there WERE error messages, but you didn't tell us WHAT they said. so we know "it doesn't work" and still can only guess ... and no, it doesn't help to "erase those 3 lines of code", or maybe it does. which 3 lines? 3 random lines? the problem: it doesn't look too wrong, no obvious syntax errors or anything. it could work. but it's done in a nonsensical way.

  • first, parent::closeConnection($db); is dead code, because the function either returns true or false, and never reaches the code (parent::closeConnection($db); ) below. that won't do any damage, because normally database connections are closed automatically at the end of the script. it may be even better this way, if getConnection returns an existing handle, otherwise it would open/close connections for every query. yes, thats bad. either open the connection once at the beginning of your script, or if you use it the first time.

  • your catch statement doesn't make much sense. you obviously don't handle the error, you just pass the exception along (i'm not even sure if that's legal. altought you could achieve the same by ignoring the whole exception handling stuff). do you handle it somewhere else?

  • the username-string in your sql-query is not escaped, so maybe an attacker could use it for sql-injection. depends on where you get your username from. you sure you sanitized everything?

  • you open the a-tag outside of the if-statement, but close it inside. that's not illegal, because it works. but it's ugly. moreover, it's nice you still have the link even though you already voted. so, you can upvote an article more than once? i doubt it. i think you should be able to withdraw your vote, but imho it would be better to have a separate action for this. upvote and unvote maybe? readability, maintainability, i'm not your mother, but please keep your codebase clean (and yes, i'm a hypocrite).

let's analyze your if-statement:

if($articles[$index]->has_voted($articles[$index]->getUsername()) == true) { ...

there's something smelly: $articles[$index]->getUsername(). i assume $article->getUsername() returns the username of the author of the article. so you're checking if the author of the article already voted on his own article. what you probably want to do is mark all the posts the VISITOR, not the AUTHOR already voted on. we can't help you with that because we don't know the code for getting the visitors data (something $_SESSIONish).

  • so, assuming you want to mark the articles the user already voted on. and kiubbo shows 30 articles on it's front page. that means you run sql-queries in a loop, 30 queries for every page view when you need exactly zero for this. why zero instead of one? because you should LEFT OUTER JOIN the articles on the votes when you SELECT the articles. on the other hand i assume you got lot's of money for some extra SQL-servers and the proficience to do the replication-dance.

  • this one isn't critical but ... you do your select on the username. aren't there any IDs? like, primary key INT(11) authorID?

enough now.

Schnalle