Psycho
Moderators-
Posts
12,157 -
Joined
-
Last visited
-
Days Won
129
Everything posted by Psycho
-
Then store the 'formatted' divs in variables (like an array as suggested earlier) then output the variables wherever you want them. YOU failed to provide enough details about what you were doing, YOU failed to provide any "real" code to allow us to really understand what you are working with and what you are trying to achieve, and YOU changed the requirements. So, basically, you just failed - which is why the other responder got fed up with you. If you take the time to adequately explain your problem people are happy to help. When you fail to do so you will find that those willing to respond will be few and far between. This is an extremely simple problem: <?php /List out specific fields instead of using '*' $query = "SELECT testimonial, name, title, image, url FROM testimonials INNER JOIN table1 ON testimonials.something = table1.something INNER JOIN table2 ON testimonials.something = table2.something ORDER BY RAND() LIMIT 3"; $result = mysqli_query($dbc, $query); //Create an array to store the testimonial output $testimonials = array(); //Format each testimonial and store as new element in array while ($row = mysqli_fetch_array($result, MYSQL_ASSOC)) { //Create new testimonial output $output = "<blockquote>\n"; $output .= "<span class=\"quotes leftq\"> “</span>{$row['testimonial']}<span class=\"rightq quotes\">„ </span>"; $output .= "<\blockquote>\n"; $output .= "<img src=\"{$row['image']}\" width=\"90\" height=\"90\" />\n"; $output .= "<h2>{$row['name']}</h2>\n"; $output .= "<h6>{$row['title']}</h6>\n"; //Add output to array $testimonials[] = $output; } ?> <div class="container"> <input type="radio" name="nav" id="first" checked/> <input type="radio" name="nav" id="second" /> <input type="radio" name="nav" id="third" /> <label for="first" class="first"></label> <label for="second" class="second"></label> <label for="third" class="third"></label> <!-- HTML COde for the testimonial ouput --> <div class="one slide"> <?php echo $testimonials[0]; ?> </div> <div class="two slide"> <?php echo $testimonials[1]; ?> </div> <div class="three slide"> <?php echo $testimonials[2]; ?> </div> </div>
-
@simpso: I would strongly advise you to NOT have your scripts jump in and out of PHP tags like you had and instead do something closer to what Jessica provided. Using the type of format you were using makes it very difficult to spot these types of problems. Also, in the future, please put [ code ] [ /code ] tags (without the spaces) around your code in the posts so it will be properly formatted (as you can see in Jessica's post above).
-
You have two options that I know of: 1) First do a SELECT query to check for a duplicate value. If one exists provide an appropriate message and don't do the insert. The only problem with this method is "race condition" issues. It is *possible* that in the very brief amount of time that you check for a duplicate then insert the new record that someone else create a new record with that duplicate value. If that happens then the insert will fail. But, unless you have a site with a LOT of traffic this is a very remote possibility. 2) Do the insert - then when it fails check the error message. If the insert fails because of a duplicate value in a unique column the error will be something like "#1062 - Duplicate entry '55' for key 'PRIMARY' ". The problem with this is that there could potentially be multiple errors but only one would be returned. So, you may have to do additional logic to verify all error conditions.
-
//List out specific fields instead of using '*' $query = "SELECT testimonial, name, address, image, url FROM testimonials INNER JOIN table1 ON testimonials.something = table1.something INNER JOIN table2 ON testimonials.something = table2.something ORDER BY RAND() LIMIT 3"; $result = mysqli_query($dbc, $query); $output = ''; $count = 0; while ($row = mysqli_fetch_array($result, MYSQL_ASSOC)) { $count++; //Add additional data from query as needed $output .= "<div class=\"testimonial-{$count}\">"; $output .= "<p>{$row['testimonial']}</p>"; $output .= "</div>"; } echo $output;
-
You only posted 9 lines of code. So, either there is more code - in which case you should have pointed out which one is line 69 - or the error is in a different file. But, as Jessica pointed out you don't have containing curly braces around the code for your if/else conditions. For an IF statement, it is valid to have the condition followed by a SINGLE statement without any grouping. But, if you have multiple statements to go with a condition you must create a statement group. Also, it is not valid (pretty sure) to have an ELSE statement without some type of structure to separate the code appropriately. I suggest you take a look at the following three pages in the manual (they are not long): http://php.net/manua...ructures.if.php http://php.net/manua...ctures.else.php http://php.net/manua...ures.elseif.php Also, you have an error in your query - table/field names should be enclosed in BACK quotes, not strait quotes.Values/strings should be enclosed in strait quotes. But, you don't need to enclose table/field names in quotes unless they are reserved words or contain characters such as a space - but you shoudl avoid those anyways. mysql_query("INSERT INTO `cart` (`User_ID`) VALUES ('$CartID')");
-
You could write a book on this subject - and I believe there are plenty. In fact, the same question(s) and variations on them have been asked numerous times on this forum. There is no way to provide anywhere near a complete response on such a question in a forum post. I suggest you do some searching for good tutorials on the subject. But, I will provide one piece of advice that I believe is absolutely crucial: Always analyze in what context a piece of data is to be used and understand the potential problems that can occur in that process. Then learn how to safeguard against those problems. For example: For data that is used in a query, each "type" of data can require different methods of validating/sanitizing. If a piece of data should be an integer then verify it is an integer or force it to be one. The real_escape_string method on safeguards against malicious string data - using it on a value that should be an integer will prevent sql injection but can still allow the value to cause the query to fail.
- 12 replies
-
- sql
- sql injection
-
(and 1 more)
Tagged with:
-
You would also index columns used to JOIN your tables. When you JOIN tables the conditions for the JOIN are treated just like a WHERE condition even if not directly in a WHERE clause (i.e. using the ON or USING conditions). In fact, it is probably more important to index columns used for JOINing your tables than those that may only be used in a WHERE clause.
-
After you check all the "basic" (required fields, lengths, formats, etc.) validations you should put an IF condition to do the database validations ONLY if all the basic validations passed. Your elseif to check for existign values is only run if the LAST if condition was NOT true. Plus, Your code to insert the record is an else condition on the count of errors - so the insert would only occur if there WAS an error in the string validation! No need to use specific indexes on the error array - just let PHP do it for you. In your database validation logic you are creating a lot of unnecessary variables. Also, you should definitely make the columns for username and email address as unique in your table. Otherwise, even with your logic you could - potentially - end up with duplicate values due to race conditions. And, if you do that, you could change the logic to attempt the insert first, and if it fails then check for duplicates Lastly, your method should not be echoing the message "Thank you for registering". It should instead return true, if successful, or false if there were errors. Here is a rewrite of your logic. Not tested, so there could be some syntax errors public function Reg() { global $database; //Perform initial string validations if(empty($this->username)){ $this->errors[] = "You forgot to enter your Username."; } if(empty($this->email)){ $this->errors[] = "You forgot to enter your email."; } if(empty($this->last_name)){ $this->errors[] = "You forgot to enter your last name."; } if(empty($this->first_name)){ $this->errors[] = "You forgot to enter your first name."; } if(empty($this->password)){ $this->errors[] = "You forgot to enter your password."; } if ($this->password != $this->password2) { $this->errors[] = 'Your password did not match the confirmed password.'; } //If string errors, perform database validations if(count($this->errors)==0) { // Register the user in the database... $query = "SELECT username FROM users WHERE username ='{$this->username}' LIMIT 1"; $result = mysql_query($query, $database->connection); //Check that query succeeded if(!$result){ $ $this->errors[] = "There was an error validating your username."; //Uncomment this line for debugging //$this->errors[] = "Query: {$query}<br>Error: " . mysql_error(); } elseif(mysql_num_rows($result)) { $this->errors[] = "That username already exists"; } //Username check OK $query = "SELECT email FROM users WHERE email ='{$this->email}' LIMIT 1"; $result = mysql_query($query, $database->connection); if(!$result){ $this->errors[] = "There was an error validating your email."; //Uncomment this line for debugging //$this->errors[] = "Query: {$query}<br>Error: " . mysql_error(); } elseif(mysql_num_rows($result)) { $this->errors[] = "That email already exists"; } } //If no string or database validation errors, insert record if(count($this->errors)==0) { $query = "INSERT INTO users (username, password, first_name, last_name, email) VALUES ('{$this->username}','{$this->password}','{$this->first_name}','{$this->last_name}','{$this->email}')"; $result = mysql_query ($query, $database->connection); //Check for query error if(!$result) { $this->errors[] = "There was an error creating the record."; //Uncomment this line for debugging //$this->errors[] = "Query: {}<br>Error: " . mysql_error(); } } //Return true if no errors, false otherwise return (count($this->errors) == 0); }//End of Reg
-
You can run queries through PHP, correct?
-
Two things: 1. Have you indexed the columns that are being used in your JOINs 2. Instead of doing the subquery, just JOIN the log records onto the query and GROUP by them to get the count SELECT u.id, u.name, u.age, p.name, p.code, a.time, a.kin, b.lime, g.happen, COUNT(logid) AS tot FROM users u LEFT JOIN products p ON p.id = u.prodid LEFT JOIN ages a ON a.id = u.ageid LEFT JOIN book b ON b.id = u.bookid LEFT JOIN group g ON g.id = u.groupid LEFT JOIN log l ON logid = u.id AS tot WHERE u.name != 'admin' GROUP BY logid ORDER BY u.id DESC LIMIT 10,40
-
The query I provided should return the username value from the users table and all the fields from the articles table. If that is not happening then you have changed the query from what was provided or the field titled "username" does not, in fact, hold what you think is the username value. That would only happen if there is no record in the users table which has an id of 0. And that IS common. Typically, auto-increment fields start at 1. But, if you do have a record with an ID of 0 the query would work perfectly fine. I'm thinking your problems may be related to this That seems to me that you weren't positive in the process you did to accomplish that. Could it be you populated the IDs incorrectly?
-
Based upon the example query in your first post, give this a try SELECT users.username, articles.* FROM `users` INNER JOIN `articles` ON articles.author = users.id
-
First of all my signature states I expect the person that I create the code for to take the time to debug it for minor errors. I'm typically just providing code as a framework. I expect the person to read through the code I provide (especially the comments) and understand it rather than blindly copy/pasting it in. But, I am always happy to help debug more troublesome issues. When someone just states "I get this error" it tells me they spent zero time trying to figure it out for themselves. But, in this instance there is absolutely nothing I can do to help. In your original code you had a function that required an input parameter called $queue which was obviously an array since it was used in a foreach() loop. In the code I provided I also used an input parameter called $queue with the expectation that it would be an array. In the usage example I provided I gave you this //Usage echo listQueue($arrayOfFileNames, $StringOfPath); I thought I named those example variables plainly enough so that I didn't have to spell out what the expectation was for their contents. Did you define $arrayOfFileNames and $StringOfPath appropriately (or use other appropriate variables of the correct type) when calling the function?
-
I would put ALL the data into a multidimensional array - then do the sort - then do the output. function sortFilesByTime($a, $B) { //Sort descending by time value return $b['time'] - $a['time']; } function listQueue($queue, $path) { //Create array to store all file data $fileArray = array(); //Put files data into a multi-dimensional array foreach ($queue as $file) { $full_path = $path . $file; list($width, $height, $type, $attr) = getimagesize($full_path); $fileArray[] = array( 'name' => $file, 'path' => $full_path, 'dload' => str_replace('./download/', '', $full_path), 'width' => $width, 'height' => $height, 'type' => $type, 'attr' => $attr, 'size' => imageSize($full_path), 'time' => filemtime($full_path), 'date' => date("F d, Y", filemtime($full_path)) ); //Sort array using custom function usort($fileArray, 'sortFilesByTime'); } //Create the output $output = ''; foreach($fileArray as $file) { $output .= "<a href=\"{$file['path']}\">"; $output .= "<img src=\"getimage.php?img={$file['dload']}&w=140&h=79\" alt=\"{$file['date']}\" title=\"Resolution: {$file['width']}x{$file['height']}Filesize: {$file['size']} Date Uploaded: {$file['date']}.\" />"; $output .= "</a>"; } //Return the output return $output; } //Usage echo listQueue($arrayOfFileNames, $StringOfPath);
-
No. Yes. Just do a query to do all that work for you. Here is an example that will return the top 10 most visited pages (assuming there is a separate record for each page hit) SELECT pageID, COUNT(pageID) as hits FROM stats_table GROUP BY pageID ORDER BY hits DESC LIMIT 10
-
OK, here is a rewrite of your code in what I consider a more logical flow which will do a correct validation of those values. But, for the sake of efficient code I made a change that requires you to modify your form. Instead fo the fields being named 'sum', 'sum2', 'sum3', etc. you should make them an array. So the names should be like this Score 1: <input type="text" name="scores[1]" /> Score 2: <input type="text" name="scores[2]" /> Score 3: <input type="text" name="scores[3]" /> . . . Note: I'm not sure I understand everything about what your expectations are so some processes may not be to your needs <?php function sanitize($in) { return htmlspecialchars(strip_tags(trim($in))); } function validScore($score) { return (is_int($val) && $score>= -20 && $score <= 20) } if(isset($_POST['processForm'])) { //Create variable to track errors $errors = array(); //Validate location $location = sanitize($_POST['location']); if($location=='') { $errors[] = "You have not provided a valid location"; } //Validate scores for holes 1 - 9 explicitly $sums = array_map('trim', $_POST['scores']); for($hole_no=1; $hole_no<=9; $hole_no++) { if(!isset($sum[$hole_no]) || !validScore($sum[$hole_no])) { $errors[] = "You haven't entered a valid score for Hole {$hole_no}"; } } //Validate total par ## ?? Shouldn't this just be calculated based on the score of each hole ?? $totalpar = trim($_POST['totalparscore']); if(!ctype_digit($totalpar) { $errors[] = "You haven't entered a valid score for Total Par Score"; } //If no validation errors attempt to enter record if(!count($errors)) { $connect_solning = mysql_connect($hostname_connect, $username_connect, $password_connect) or trigger_error(mysql_error(),E_USER_ERROR); @mysql_select_db($database_connect) or die (mysql_error()); $user_id = 7; $location = mysql_real_escape_string($location); $sql = "INSERT INTO snag_scores (user_id, location, sum1, sum2, sum3, sum4, sum5, sum6, sum7, sum8, sum9, totalpar) VALUES ('$user_id', '$location', '$sum[1]', '$sum[2]' '$sum[3]', '$sum[4]', '$sum[5]', '$sum[6]', '$sum[7]', '$sum[8]', '$sum[9]', $totalpar)"; $result = mysql_query($sql); if(!$result) { $errors[] = "Error running query: $sql<br>Error:" . mysql_error(); } } //Check if record was inserted if(!count($errors)) { //Record was added echo "<br/> A score for {$location} has now been added.<br>\n"; foreach($sums as $hole => $score) { echo "{$hole}: {$score}<br/>\n"; } echo "Total: {$totalpar}"; } else { //There were errors - display them echo "The following errors occured:\n"; echo "<ul>\n"; foreach($errors as $err) { echo "<li class=\"white\">{$err}</li>\n"; } echo "<ul>\n"; } } ?>
-
You should really reconsider your "sanitize" function. But to your problem, you have a validation check that only outputs a message. It then proceeds to try and insert the record anyway! So, you first need to work on the validation to reject anything that does not pass. As to the 0 value, check the manual for empty() - it will return true for empty strings or anything considered false (e.g. 0). So, what SHOULD that validation really be. I think you would want to ensure that value is a positive integer. Is that correct? If so, empty is the wrong type of validation. Is there a maximum value you want to enforce?
-
Or create the multiple outputs at the same time when running through the query results the one time. Just assign the outputs to two different variables and output the variables where you need those contents. You should be doing this anyway, in my opinion, to separate the logic and the presentation. But, I'm also guessing that since you are using $row['id'] as a parameter in your query(ies) that the code above is being run within a loop of another query! Why aren't you using a JOIN to that unseen query? I just noticed that those two outputs are exactly the same?! Not sure if that is what you really meant to do or if it is only an example. But, assuming you want the two outputs to be different for the same query, this is what I would do: <?php $query = "SELECT follow_user_id, logo, company FROM follow JOIN users WHERE user_id = {$row['id']} ORDER BY follow_user_id ASC LIMIT 10" $result = mysql_query($query); $followImageHTML = ''; $followButtonHTML = ''; while($row = mysql_fetch_array($result)) { //Create two different sets of output using the same query $followImageHTML .= "<div class=\"followimage\">\n";; $followImageHTML .= "<a href=\"/test/profileinserttest.php?ID={$row['follow_user_id']}\">"; $followImageHTML .= "<img src=\"/test/images/{$row['logo']}\" alt=\"{$row['company']}\" />"; $followImageHTML .= "</a>\n"; $followImageHTML .= "</div>\n"; $followButtonHTML .= "<div class=\"followimage\">\n"; $followButtonHTML .= "<a href=\"/test/profileinserttest.php?ID={$row['follow_user_id']}\">"; $followButtonHTML .= "<img src=\"/test/images/{$row['logo']}\" alt=\"{$row['company']}\" />"; $followButtonHTML .= "</a>\n"; $followButtonHTML .= "</div>\n"; } ?> <div class="followbuttonimagearea"> <?php echo $followImageHTML; ?> </div> <div class="followbuttonimagearea"> <?php echo $followButtonHTML; ?> </div>
-
Same here. The results from your functions above are exactly as I would expect based upon your input. And, what you are doing is probably the most inefficient manner in which to do that. But, apparently that is not what you are trying to do anyway. So, provide an example of the input array and what you want for the output.
-
You have the onclick events defined for the DIV, but then use a link tag inside that. Either, put the onclick events on the DIV and don't use a link tag inside the did OR put the onclick events on the link tag. You can also create a single function to show or hide the form. <html> <head> <script type="text/javascript"> function showhide(objID) { var obj = document.getElementById(objID); var visibilityStatus = (obj.style.visibility!='visible') ? 'visible' : 'hidden'; obj.style.visibility = visibilityStatus; return false; } </script> </head> <body> <div><a href="#" onclick="return showhide('tip');" ondblclick="return showhide('tip');" class="clickme">Search</a></div> <div id="tip" style="position: relative; visibility: hidden;"> <form method="get" id="search_block" action="<?php echo home_url(); ?>" > <label for="search_field_block"></label> <!-- end auto clear label --> <input type="text" name="s" id="search_field_block" value="" /> <!-- end search field --> <input type="submit" id="search_submit_block" value="GO" /> <!-- end search submit --> </form> <!-- end search form --> </div> </body> </html>
-
As opposed to what? If either of the IDs are not set, don't execute the code. If you are wanting someone to prevent using Refresh to insert a new record there are several options. Here are two: 1. After the record is added, redirect the user to a different (or the same) page using a header() function. This will wipe out any GET/POST values. 2. Put in logic to prevent a duplicate records
-
It's impossible to know what the problem is based upon what you have provided. For example, where is $row['id'] defined? But, the more important thing is that the little error handling there is provides no feedback. So, if there was a problem you have no way to know what it is. You are defining $followerid as $_SESSION['userID'], but what if the session wasn't started (I actually think the problem is something to do with sessions)? Then, $followerid would have a 'false' value and the query would fail. But, there is nothing to check if $_SESSION['userID'] is defined and if the query fails there is nothing to provide an error. Also, I'm not sure if you stripped out some code or not, but this makes no sense: $error = ""; if($error == "") { Why would you set $error to an empty string immediately followed by a condition check to see if it is an empty string? Based upon what I see in that code I think you may be running queries in loops - which is a bad idea, but since there is not enough information provided I can't provide a solution for that. Give this code a try to at least pinpoint the problem. <?php $errors = array(); //Validate the input vars if(!isset($_SESSION['userID'])) { $errors[] = "\$_SESSION['userID'] value is not set."; } if(!isset($row['id'])) { $errors[] = "\$row['id'] value is not set"; } if(!count($error)) { //Validation of input vars passed, attempt to run query //Force vars to be ints to be safe for query statement $followerid = intval($_SESSION['userID']); $profileid = intval(($row['id']); $query = "INSERT INTO `follow` (`user_id`, `follow_user_id`) VALUES ('{$profileid}', '{$followerid}')"; $result = mysql_query($query); if (!$result) { $errors[] = "Query: {$query}<br>Error: " . mysql_error(); } } if(count($errors)) { echo "The following errors occured:\n"; echo "<ul>\n"; foreach($errors as $rr) { echo "<li>{$err}</li>\n"; } echo "</ul>\n"; } ?> </div> <?php echo $profileid; ?> Profile ID <br> <?php echo $followerid; ?> Follower ID <br> </div> <div class="followbutton"> <a href="<?php echo $_SERVER['PHP_SELF']; ?>"><img src="/images/follow.png" id="followbutton" class="submit-button"/></a> </div>
-
This is actually quite easy. You just need to do the following: 1. Change the .js file to a php file. Then change all of the javascript src attributes to use the newly named file. (Note: the file used for a javascript src does not need to be .js - it can be anything) Now, when the HTML page loads and attempts to load the content it will be loading a php file instead so you have full control over the content returned. 2. In the newly renamed PHP file put in whatever logic you want to include/remove certain line of code
-
There is no one size fits all answer because it is entirely dependent upon the purpose. But, I'll provide some best practice advice If the value is required for the page you can either use a default value when no ID is passed or provide an appropriate error. . . . I typically just force the value to be an integer by casting it as an integer or using intval(). For non-integer values it will be set to 0 which - in most cases won't have a corresponding value in the database since auto-int fields typically start at 1. So, the rest of the logic will go as normal and just respond with a "not found" type error (i.e. your #5) This is completely unnecessary if you have already validated if the value is an integer (or forced it to be in int). mysqli_real_escape_string() is only needed for "string' data My logic would probably look something like this $id = (isset($_GET['id'])) ? intval($_GET['id']) : 0; $query = "SELECT * FROM table WHERE id = '{$id}'"; $result = mysql_query($query); if(mysql_num_rows($result)) { //No result found, show appropriate error } else { //Display the record } NOTE: The one thing I left out was any validation needed if the record required specific "rights" for the user to view. In that case you may need to do a check for the user rights before running the query for the record or it may require a more complicated select query
-
I assume you want the number of images displayed to be the same as the value of $user_rating_show in which case you can just create a loop for($i = 1; $i <= $user_rating_show, $i++) { echo "<img src='../img/beer_mug_finish-green.jpg' alt='beer_m' name='beer_mug' width='34' height='33'>"; } or you could use str_repeat(), but I would prefer the loop for ease of understandability echo str_repeat("<img src='../img/beer_mug_finish-green.jpg' alt='beer_m' name='beer_mug' width='34' height='33'>", $user_rating_show);