Psycho
Moderators-
Posts
12,157 -
Joined
-
Last visited
-
Days Won
129
Everything posted by Psycho
-
My name is not "Guru", my name is "Psycho". "Guru" is a tag that members can earn in this forum if they are productive and helpful here. Looking at the questions table structure you have the following columns: `ques_id`: The question ID `q` : The question text `op1`: Answer #1 `op2`: Answer #2 `op3`: Answer #3 `op4`: Answer #4 `cop`: The correct answer (1-4) If you will never, ever need more than four answers this will be fine. But, to be truly robust the answers should be in a separate table. You also have a subjects table, but there is no "subject" identifier for the questions. If you are going to have different questions for different subjects you will want a subject_id column in the questions table. So, assuming you have done that and you know the subject for which you want to display the questions and answers - this should work: //Determine which subject to display the questions for $subject_id = intval($_GET['subject']); $query = "SELECT ques_id, q, op1, op2, op3, op4 FROM question5 WHERE subject_id = {$subject_id}"; $result = mysql_query($query) or die(mysql_error()); //Put results into an array $questions = array(); while($row = mysql_fetch_assoc($result)) { //Put answers into a temp array $answers = array($row['op1'], $row['op2'], $row['op3'], $row['op4']); //Randomize the questions array shuffle($answers); //Add the question and randomized answers to the $questions array $questions[] = array( 'ques_id' => $row['ques_id'], 'q' => $row['q'], 'answers' => $answers ); } //After all questions have been put into an array, //randomize the order of the questions shuffle($questions); //Output the list of questions and answers $output = "<ol>\n"; foreach($questions as $ques) { $output .= "<li>\n"; $output .= "{$ques['q']}<br>\n"; foreach($ques['answers'] as $ans) { $output .= "<input type='radio' name='answer[{$ques['ques_id']}]' value='{$ans}'> {$ans}<br>\n"; } $output .= "</li><br>\n"; } $output .= "</ol>\n"; echo $output; If you do not need questions for different subjects and there is only one set of questions, just remove the WHERE clause in the query.
-
If it is a production server - then it is already out there. If the data should not be publicly accessible then it needs to be secured behind a login or some other process. Obfuscation is never a replacement for security.
-
Do you realize that your update query is hard coded for specific values and does not use the values passed in the POST data? So, every time you run that page you will have the same value int he database. So, you probably aren't seeing any changes because of that.
-
I was thinking the same thing. Although RegEx is typically slower than string comparisons, in this case it's probably easier to execute a single RegEx against the entire file contents than creating ana array and looping through it. But, a database beats both of those ideas anyway.
-
and "Usero Nameo" is not Spanish.
-
Well, your preg match is looking for anything that contains "127.0.0.1", which is contained in "127.0.0.12". You could change the regex to look for values that match the value which begin and end with a "word boundary" (line break, space, tab, etc.) if( preg_match( "#\b{$ip}\b#", $file ) Although you would be better off storing this in a database to make management easier.
-
Yes, where is your code? We have no idea what your table structure is or how you need to query the questions/answers. I'm not really sure if you are wanting the questions in a random order or the possible answers in a random order. But, my answer will be the same. Since a quiz/test will be a relatively short list of records, I would query the database to get a list of all the questions and associated answers. Then I would dump the results into an array and use shuffle() to randomize with the order of the question, the order of the answers, or both.
-
I'm with Maq. Verify exactly where the problem is. But, with respect to the above code, why on earth would you loop through an array for something like that when there are built-in functions that would make it much simpler. I see one thing in the code that doesn't make sense - which DaveyK alluded to. You are only finding the first item that does not exist in the array instead of checking all that are unassigned. Not sure if that is your intent or not. If so this shoudl suffice protected function _reset_run($ar_reset_items) { //Get the array of keys $ar_reset_keys = array_keys($ar_reset_items); //Get the list of keys that are not in this->ar_store_array $unassigned_keys = array_diff($ar_reset_keys, $this->ar_store_array); if(count($unassigned_keys)) { //Use first unassigned key to add value to $this->$item $first_unassigned_key = array_shift($unassigned_keys); $this->$item = $ar_reset_keys[$first_unassigned_key]; } }
-
I agree with kicken. I wouldn't make this more complicated than it needs to be. Your proposed database design in post #3 would be a perfectly normalized design. But, that is not always needed or preferred. I would have to assume that for any languages supported you will always have a value for each "placeholder" for each language. Plus, adding a new language is not something that is done in piecemeal. It should be done all at once. I would have a single table that has a field/column for the text ID or placeholder tag and then additional fields/columns for each each language id | text_en | text_de | text_sp username User name Gebruikersnaam Usero Nameo Then, when you need the text for a page, only SELECT the column with the text you want based on the user's language. As kicken suggested you could also filter the query based on the specific texts that you need. Something like: $lang = 'en'; //This is determined programatically $query = "SELECT text_{$lang} FROM translations WHERE ID IN ($commaSeparatedListOfPlaceHolderIDs)";
-
You should typically index any fields that are used to JOIN tables or are commonly used as filtering (i.e. used in the WHERE clause). So, you would want to index a client_id, but not necessarily the client name - even if the name can be used for search criteria. In this case, you definitely want the user ID indexed in all the tables where it is used in these queries. Without understanding the table structure and how the data exists, it is difficult to give you complete suggestions. First off, I see you are doing a JOIN on the items table - but there is nothing from that table used in the query. So, it seems that is not needed - or you left something out. But, with the data for the "stuff" table I think you can get the results you want without all the subqueries - which is probably the biggest problem. Since I don't have any data to test with I'm not 100% confident this will work, but give it a try (it may at least get you started int he right direction) SELECT u.id, u.name, u.email, u.myid, COUNT(s.userid) AS apps, SUM(s.gone > 0) AS gone_total, SUM(s.action = 3) AS exist_total, (SELECT COUNT(*) as Num FROM `customers` WHERE `userid` = u.id) AS customer_total FROM users AS u LEFT JOIN stuff AS s ON s.userid = u.id GROUP BY u.id -- LEFT JOIN items i ON i.id = u.my_id For the data from the "stuff" table I just JOINed all the records using the user id. Then for apps, take a count of the records by user id. For gone_total I take the sum of "(s.gone > 0)". That should be evaluated as a true (1) or false (0). So, it would be a count of all the records (by user id) where that condition is true. I used the same logic for exists_total. However, I couldn't think of a way (right now) to remove the subquery for the customers table. If I was to JOIN that on the query it would corrupt the results from the stuff table.
-
"transforming" a table list to a comma-separeted list instead?
Psycho replied to xwishmasterx's topic in PHP Coding Help
Please see the edit in my last response. -
"transforming" a table list to a comma-separeted list instead?
Psycho replied to xwishmasterx's topic in PHP Coding Help
Did you try either of my suggestions? EDIT: I could have sworn your original question mentioned getting the records from the database, but I see you state they are in an array. But, I see the values are in an array with each value in different sub-arrays. So, you can to put the values in a single-dimensional array and then implode them. Basically what I already suggested in option 2. $names = array(); foreach($cast as $record) { $names[] = $record['name']; } $stringData = implode(', ', $names); -
"transforming" a table list to a comma-separeted list instead?
Psycho replied to xwishmasterx's topic in PHP Coding Help
Well, it depends. If the list is small and the total length will be less than 1024 characters, you can do it directly in the query using GROUP_CONCAT(). Otherwise, you can just process the result set into an array and use implode(). Using query SELECT GROUP_CONCAT(field1) as field1List FROM table_name GROUP BY field2 Using PHP $field1Values = array(); while($row = mysql_fetch_assoc($result)) { $field1Values[] = $row['field1']; } $field1List = implode(', ', $field1Values); -
Forum Rules: You seriously bumped your thread after TWO MINUTES? Anyway a quick google search led me to the PHP manual page for date_default_timezone_set() (The actual error message probably would have been faster, but you declined to provide it). On that page is the following information: So you should probably use that function to set the timezone in your PHP script.
-
The error "Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given" means that your query is failing. But, you should NOT be trying to query 100 records at a time. It will put more load on the server by doing that than it would to just run one query. You should only do something like that when you are implementing pagination - i.e. only showing 100 (or some number) of records on a page at a time. But, the problem look s pretty obvious to me - which you would have found if you did some simple debugging, such as checking for the error and/or echoing the query to the page. Your query is this: 'SELECT page_title FROM testdb.test_page WHERE (page_id >='.$x.' AND page_id < '.$y.'AND page_category = 5' If $x is 1 and $y is 100, the parsed query would be: 'SELECT page_title FROM testdb.test_page WHERE (page_id >=1 AND page_id < 100AND page_category = 5' Do you notice that there is no space between "100" and the word "AND"? That is why I don't like to create strings with variables by concatenating the variables outside the quotes strings. I prefer to use double quoted strings and put the variables inside the quotes. makes it much easier to read, in my opinion. And, even more important - don't create the query inside the mysql_query() function. Create it as a string first. Then, if there is an error, you can echo the query to the page to inspect it. $query = "SELECT page_title FROM testdb.test_page WHERE (page_id >= $x AND page_id < $y AND page_category = 5"; $result = mysql_query($query) or die("Query: $query<br>Error: " . mysql_error()); But, as I said, you are doing more harm than good by trying to break up the query into chunks. Just query all the records.
-
I have to disagree slightly. Server-side validation should be #1 and a requirement. Client-side validation is a "nice to have" but not a necessity, so it should be considered #2.
-
Well, it could be any number of things. I think it is pretty obvious that the query was failing, but why it was failing is impossible to determine without knowing what is being passed to the form. You should add error handling to your query to output the actual error from mysql as well as the query. My guess would be that some of the variables you are using in the query were either not getting defined OR they were getting defined with values that made the query invalid. So, here is the query: $statement = mysqli_query($condbyear2, "SELECT UQN FROM $tablefinal WHERE difficulty= '$correctdiff'"); $condbyear2 is not defined in that script - I assume it is defined in the include file. The query itself has two variables. $tablefinal is defined here: $tablefinal = $tbl.$qtype; So, now we have to look at where those two variables are defined. $tbl is defined within this code if (($_SESSION['year2']) || ($_SESSION['y2s1'])) //alowed subscriptions { switch ($module) //creating whitelist, used for security, prep_stmt can't be used and is better than using escae_string { case "neuro": $tbl = "Neuro_"; break; case "gi": $tbl = "GI_"; break; case "epi": $tbl = "EPISTATS_"; break; } } if (($_SESSION['year2']) || ($_SESSION['y2s2'])) //allowed subscriptions { switch ($module) { case "genetics": $tbl="Genetics_"; break; case "renal": $tbl="Renal_"; break; case "endocrine": $tbl = "Endocrine_"; break; } } The problem with that is that there are two if() conditions and then switch()es within those without a default. So, if neither of the two if conditions are true OR if one of the two if conditions are true but none of the case statements are true, then $tbl will not be defined and the query will fail. You should code your pages to handle situation when you do not receive the input you expect. It could be that the logic is wrong or that you are receiving input you didn't expect. The code to define $qtype has the sameproblem in that it will only get defined based upon three specific values in a switch(). But, now I see why you are having the problem and it is this: if (($module="") || ($diff="") || ($questiontype="")) { echo "Filter fields not correctly specified!"; die(); } In that if() condition you are ASSIGNING values to those variables not COMPARING them.
-
I would probably rewrite the sections towards the bottom with the switch statements to be more efficient as well. But, this will clean up the logic for creating the select options and will be much, much easier to maintain. Not promising I didn't make a syntax error or two but you should be able to fix them if there are and you should be able to see the benefit of using this type of implementation. <?php if (($_SESSION['year2']) || (($_SESSION['y2s1']) && ($_SESSION['y2s2']))) { echo "<h3>".$_SESSION['year2']."</h3>"; } if ($_SESSION['y1s1']) { echo "<h3>".$_SESSION['y2s1']."</h3>"; } if ($_SESSION['y2s2']) { echo "<h3>".$_SESSION['y2s2']."</h3>"; } $module = $_GET['mod']; $questiontype = $_GET['type']; $diff = $_GET['diff']; function createSelectOptions($optionsList, $selectedValue) { $optionsHTML = ''; foreach($optionsList as $value => $label) { $selected = ($selectedValue==$value) ? ' selected="selected"' : ''; $optionsHTML .= "<option value='{$label}'{$selected}>{$label}</option>\n"; } return $optionsHTML; } //Determine list of topic options if (($_SESSION['year2']) || (($_SESSION['y2s1']) && ($_SESSION['y2s2']))) { $topicOptionsList = array( 'all' => 'ALL MODULES', 'neuro' => 'Neuroscience', 'gi' => 'Gastrointestinal and Liver', 'epistats' => 'Epidemiology and Statistics', 'genetics' => 'Clinical Genetics', 'renal' => 'Renal and Urology', 'endocrine' => 'Endocrine', 'sem1' => 'SEMESTER 1 MODULES', 'sem2' => 'SEMESTER 2 MODULES' ); } elseif ($_SESSION['y2s1']) { $topicOptionsList = array( 'sem1' => 'SEMESTER 1 MODULES', 'neuro' => 'Neuroscience', 'gi' => 'Gastrointestinal and Liver', 'epistats' => 'Epidemiology and Statistics' ); } elseif ($_SESSION['y2s2']) { $topicOptionsList = array( 'sem2' => 'SEMESTER 2 MODULES', 'genetics' => 'Clinical Genetics', 'renal' => 'Renal and Urology', 'endocrine' => 'Endocrine' ); } //Create HTML output for the topic options $topicOptionsHTML = createSelectOptions($topicOptionsList, $module); //Create list of question options $questionOptionsList = array( 'all' => 'ALL FORMATS', 'mcq' => 'Multiple Choice (MCQ)', 'emq' => 'Extended Matching (EMQ)', 'srq' => 'Selected Response (SRQ)', 'mcqemq' => 'MCQ and EMQ', 'mcqsrq' => 'MCQ and SRQ', 'emqsrq' => 'EMQ and SRQ' ); //Create HTML output for the question options $questionOptionsHTML = createSelectOptions($questionOptionsList, $questiontype); //Create HTML output for the difficulty options $difficultyOptionsList = array( 'all' => 'ALL DIFFICULTIES', 'easy' => 'Easy', 'easymoderate' => 'Easy and Moderate', 'moderate' => '>Moderate', 'moderatehard' => 'Moderate and Hard', 'hard' => 'Hard', 'easyhard' => 'Easy and Hard' ); //Create HTML output for the difficulty options $difficultyOptionsHTML = createSelectOptions($difficultyOptionsList, $diff); ?> <form name="customlist" action="mcqlistquery.php" method="post"> <!-- use mcqlistcustom or just make it the same page??--> <table border="0" width="90%" align="center"> <tr><td><b>Select Modules</b></td><td><b>Select Question Format</b></td><td><b>Select Difficulty</b></td></tr> <tr> <td><select name="topic"><?php echo $topicOptionsHTML; ?></select></td> <td><select name="questionformat"><?php echo $questionOptionsHTML; ?></select></td> <td><select name="difficulty"><?php echo $difficultyOptionsHTML; ?></select></td> <td><input type="submit" value="Go!" /></td> </tr> </table> </form> <?php if (($module="") || ($diff="") || ($questiontype="")) { echo "Filter fields not correctly specified!"; die(); } include 'dbyear2.php'; if (($_SESSION['year2']) || ($_SESSION['y2s1'])) //alowed subscriptions { switch ($module) //creating whitelist, used for security, prep_stmt can't be used and is better than using escae_string { case "neuro": $tbl = "Neuro_"; break; case "gi": $tbl = "GI_"; break; case "epi": $tbl = "EPISTATS_"; break; } } if (($_SESSION['year2']) || ($_SESSION['y2s2'])) //allowed subscriptions { switch ($module) { case "genetics": $tbl="Genetics_"; break; case "renal": $tbl="Renal_"; break; case "endocrine": $tbl = "Endocrine_"; break; } } switch ($questiontype) //question format. whitelist. { case "mcq": $qtype = "MCQ"; break; case "emq": $qtype ="EMQ"; break; case "srq": $qtype = "SRQ"; break; } $tablefinal = $tbl.$qtype; switch ($diff) //whitelist { case "easy": $correctdiff = "Easy"; $imgsrc = "http://.mysite../easy.png"; $imgalt = "easy"; break; case "moderate": $correctdiff = "Moderate"; $imgsrc = "http://..mysite../moderate.png"; $imgalt = "moderate"; break; case "hard": $correctdiff = "Hard"; $imgsrc = "http://...mywebsite./hard.png"; $imgalt = "hard"; break; } $statement = mysqli_query($condbyear2, "SELECT UQN FROM $tablefinal WHERE difficulty= '$correctdiff'"); $baseURL = "http://..my website../mcq.php?uqn="; while ($row = mysqli_fetch_array($statement, MYSQLI_NUM)) { foreach ($row as $integer) { $href = $baseURL.$integer; echo "<a href= '$href'> <img src='$imgsrc' alt='$imgalt' width='80' height='80'> </a>"; } } ?>
-
Let that be a lesson to you. If you copy/paste a bunch of trivial code such as that you are bound to create those types of errors. You could have solved the same thing very easily by creating conditions to define an array of what the option list should be - then processing that array to create the actual options. What you have now would be a bear to try and maintain. But, that code you added shouldn't have any affect on the mysqli_fetch_array() call. Your problem is that the query is failing. So, you may have some problems in the code that define the variables used in the query. Try changing the function call to this: $statement = mysqli_query($condbyear2, "SELECT UQN FROM $tablefinal WHERE difficulty= '$correctdiff'") or die("Query: $query<br>Error: " . mysql_error());
-
That is because you changed the query from what I provided. The UNION clause has some specific requirements. 1) The queries must have the same number of fields (which is why I hard coded some fields with a 0). 2) The "same" fields from the queries must be of the same type 3) The "same" fields must be in the same order. In the query I provided, homeGames came before awayGames in the two sub queries. However, you changed the second sub query to have awayGames come before homeGames. In truth, you don't even need to name the columns for the second sub query since the results will be based upon the column names from the first query. I only name them to make it easier to read. So, in your version, the awayGames are considered homeGames because they are in the column position associated with homeGames in the first query. SELECT teamID, SUM(homeGames + awayGames) as gamesPlayed, SUM(homeGames) as homeGames, SUM(awayGames) AS awayGames, SUM(homePoints + awayPoints) AS totalPoints, SUM(homePoints) as homePoints, SUM(awayPoints) AS awayPoints, SUM(pointsAgainst) AS pointsAgainst FROM (SELECT homeTeamID as teamID, COUNT(homeTeamID) as homeGames, 0 AS awayGames, SUM(homePoints) as homePoints, 0 AS awayPoints, SUM(awayPoints) as pointsAgainst FROM results GROUP BY teamID UNION ALL SELECT awayTeamID as teamID, 0 AS homeGames, COUNT(awayTeamID) as awayGames, 0 as homePoints, SUM(awayTeamID) AS awayPoints, SUM(homePoints) as pointsAgainst FROM results GROUP BY teamID ) as t GROUP BY teamID ORDER BY totalPoints DESC, pointsAgainst ASC
-
$query = "SELECT id FROM table ORDER BY id DESC"; $result = mysql_query($query) or die ("no query"); $idsArray = array(); while($row = mysql_fetch_assoc($result)) { //Add each ID as a new element in the array $idsArray[] = $row['id']; } //Output the array to verify echo "<pre>" . print_r($idsArray, 1) . "</pre>";
-
But, the reason you are having a problem is that you are using GROUP_CONCAT() but you don't have a GROUP BY to group on.
-
You would save us both a lot of time if you would state all of your requirements up front. It's a little disheartening to put time and effort into helping someone only to have them come back and say "what I really want is . . . " But, what you are asking for now is trivial based upon the previous solution I provided. Just add counts for homeGames and awayGames to both the sub queries. Since the first query is for the home game data, use COUNT(teamID) to get the number of home games and hard code awayGames as 0. Then do the opposite for the other sub query. Then, lastly, do a sum on the values in the main query. SELECT teamID, SUM(homePoints + awayPoints) AS totalPoints, SUM(homePoints) as homePoints, SUM(awayPoints) AS awayPoints, SUM(homeGames) as homeGames, SUM(awayGames) AS awayGames, SUM(pointsAgainst) AS pointsAgainst FROM (SELECT homeTeamID as teamID, SUM(homePoints) as homePoints, 0 AS awayPoints, COUNT(homeTeamID) as homeGames, 0 AS awayGames, SUM(awayPoints) as pointsAgainst FROM results GROUP BY teamID UNION ALL SELECT awayTeamID as teamID, 0 as homePoints, SUM(awayTeamID) AS awayPoints, 0 AS homeGames, COUNT(awayTeamID) as awayGames, SUM(homePoints) as pointsAgainst FROM results GROUP BY teamID ) as t GROUP BY teamID ORDER BY totalPoints DESC, pointsAgainst ASC
-
1. Get the size of the image: getimagesize() 2. If image size < 750, do nothing - exit 3. Determine the percentage for the new size: 750 divided by current width 4. Determine the new height using current height times the percentage above 5. Use imagecopyresampled() to resize the image. Example #1 and the information above should be enough to get started.