Psycho
Moderators-
Posts
12,157 -
Joined
-
Last visited
-
Days Won
129
Everything posted by Psycho
-
How to sum, emit and store result from a calculation
Psycho replied to u0867587's topic in PHP Coding Help
Hmm, so you want to show the sum for the sessions in a module - but you want to display the module before the sessions? You'll need to take a different approach. I typically do this by creating a function for displaying a complete group and then use the trigger in the while() loop to call that function. Not tested: function outputModule($moduleID, $moduleName, $sessionData) { if(!count($sessionData)) { return false; } $markTotal = 0; $sessionsHTML = ''; foreach($sessionData as $session) { $sessionsHTML .= "<p><strong>Session:</strong> {$session['SessionId']} {$session['Mark']}</p>"; $markTotal += $session['Mark']; } $moduleHTML = "<p><br><strong>Module:</strong> {$moduleID} - {$moduleName} {$markTotal}</p>"; return $moduleHTML . $sessionsHTML; } $output = ""; $studentId = false; $courseId = false; $moduleId = false; while ($row = mysql_fetch_array($result)) { $moduletotal += $row['Mark']; $modulemark = (int)($moduletotal); if($studentId != $row['StudentUsername']) { //Student has changed $studentId = $row['StudentUsername']; $output .= "<p><strong>Student:</strong> {$row['StudentForename']} {$row['StudentSurname']} ({$row['StudentUsername']})"; } if($courseId != $row['CourseId']) { //Course has changed $courseId = $row['CourseId']; $output .= "<br><strong>Course:</strong> {$row['CourseId']} - {$row['CourseName']} <br><strong>Year:</strong> {$row['Year']}</p>"; } if($moduleId != $row['ModuleId']) { //Module has changed if(isset($sessionsAry)) //Don't run function for first record { //Get output for last module and sessions $output .= outputModule($moduleId, $moduleName, $sessionsAry); } //Reset sessions data array and Set values for new module $sessionsAry = array(); $moduleId = $row['ModuleId']; $moduleName = $row['ModuleName'] } //Add session data to array for current module $sessionsAry[] .= array('SessionId'=>$row['SessionId'],'Mark'=>$row['Mark']); } //Get output for last module $output .= outputModule($moduleId, $moduleName, $sessionsAry); //Display the output echo $output; } -
Complicating, no. Working, yes. The code you provided was horribly inefficient by trying to INSERT records in a loop. Database transactions are one of the most "expensive" things with respect to performance/scalability. Plus, that code would easily break due to unexpected characters in the data and would not handle incomplete/invalid records. The code I provided ensure that records are 'complete' (i.e. have a value for all the fields) rather than simply assuming the lines will always be in the same order and format. For example, what if there was an "optional" field ^ D03/04/10 T-20.28 PYOUR LOCAL SUPERMARKET OSome Optional Value ^ The code originally provided would be inserting values in the the incorrect fields. If you take a half-assed approach to something like this you will spend countless hours "repairing" things later on. You should never assume that the data you receive will be the data you expect. Doesn't matter if it is data coming from a form post or reading a data file. The above took me about 5-10 minutes and it is fairly fool-proof. But, I would have to know more about the input data to be sure. That doesn't sound like too much work for something that I would have high confidence in.
-
OK, this is only sample code. YOU should add more validation/formatting of the data. For example, I would think you would want to store the date as an actual date value and not a string. //Set input file $file = 'somefile.qif'; //Read file into array $lines = file($file); //Set variables for processing loop $type = false; $insert_records = array(); $record = array(); //Process the data foreach($lines as $line) { if($line=="^") { $record = array(); } elseif(preg_match("#^!Type:(.*)$#", $line, $match)) { $type = mysql_real_escape_string2(trim($match[1])); $record = array(); } else { switch(substr($line, 0, 1)) { case 'D': $record['date'] = mysql_real_escape_string2(trim(substr($line, 1))); break; case 'T': $record['amount'] = mysql_real_escape_string2(trim(substr($line, 1))); break; case 'P': $record['descr'] = mysql_real_escape_string2(trim(substr($line, 1))); break; } } if(count($record)==3 && $type!==false) { $insert_records[] = "('{$type}', '{$record['date']}', '{$record['amount']}', '{$record['descr']}')"; $record = array(); } } //Create one INSERT query for all records $insert_query = "INSERT INTO `transactions` (`type`, `date`, `amount`, `description`) VALUES " . implode(", ", $insert_records); Using that code and your sample data, you would get the following query: INSERT INTO `transactions` (`type`, `date`, `amount`, `description`) VALUES ('Bank', '03/03/10', '-379.00', 'CITY OF SPRINGFIELD'), ('Bank', '03/04/10', '-20.28', 'YOUR LOCAL SUPERMARKET'), ('Bank', '03/03/10', '-421.35', 'SPRINGFIELD WATER UTILITY')
-
Do NOT run queries in loops!!! It is horribly inefficient. Parse all the data then run ONE INSERT query. Plus, you need to escape teh input to prevent SQL Injection errors and I would expect you want at least some validation of the data. I'll post some sample code in a few minutes.
-
If it is simply a text file, then read it line-by-line and parse it accordingly. I have no clue what each "piece" of information is in that data and what you need and don't need. Plus, I can make some assumptions on what formats the data will always take based upon the three records you have presented, but I would only be guessing. In the above each record appears to have a Type, a Date, a Price, and some type of description. But, I don't know whether the "D" always precedes the date and is static or if it is some type of code that can change and has significance. Same thing with the "T" that precedes what appears to be the price. It is always a "T" or is that a piece of data? Lastly, the same goes for the descriptions which are (at least in the above examples) preceded by a "P". Again, is this static or a piece of data?
-
I want to output results from a query in a certain way using php
Psycho replied to u0867587's topic in PHP Coding Help
First change your query to ORDER the results by course, student. Note I also changed the order of the SELECT fields. I like to put them on separate lines by each table in the order the tables are included. Makes it easy to see what is coming from where $query = "SELECT c.CourseName, st.CourseId, st.Year, st.StudentUsername, st.StudentForename, st.StudentSurname, gr.Mark, gr.Grade, s.ModuleId,s.SessionId, s.SessionWeight, m.ModuleName, m.Credits, FROM Course c INNER JOIN Student st ON c.CourseId = st.CourseId JOIN Grade_Report gr ON st.StudentId = gr.StudentId JOIN Session s ON gr.SessionId = s.SessionId JOIN Module m ON s.ModuleId = m.ModuleId WHERE (st.StudentUsername = '".mysql_real_escape_string($studentid) . "' ORDER BY c.CourseName, st.StudentUsername, m.ModuleName"; Next, change your output code to detect changes in the course, student and module (you might need to play around with the formatting to get it how you want) $output1 = ""; $courseID = false; $student = false; $moduleID = false; while ($row = mysql_fetch_array($result)) { //$result is the query if($courseID != $row['CourseId']) { $course = $row['CourseId']; $output1 .= "<p><br><strong>Course:</strong> {$row['CourseId']} - {$row['CourseName']} <strong>Year:</strong> {$row['Year']}</p>" } if($student != $row['StudentUsername']) { $student = $row['StudentUsername']; $output1 .= "<p><strong>Student:</strong> {$row['StudentForename']} {$row['StudentSurname']} ({$row['StudentUsername']})</p>" } if($moduleID != $row['ModuleId']) { $moduleID = $row['ModuleId']; $output1 .= "<p><br><strong>Module:</strong> {$row['ModuleId']} - {$row['ModuleName']}</p>" } $output1 .= "<p><strong>Session:</strong> {$row['SessionId']} {$row['Mark']} ({$row['Grade']})</p>"; } echo $output1; -
how to check if duplicate rows across multiple columns
Psycho replied to mpsn's topic in PHP Coding Help
Do not double post. As stated in your previous post, the query is failing for some reason. You need to see what the error is by checking mysql_error() Although there could be syntax errors with respect to field/table names your problem is likely due to the fact that you put the SELECT field within parens. However, you should simply make the fields unique and to the INSERT query instead of doing a SELECT query first. -
The proposed solution "The Little Guy" provided with respect to the unique field conditions would make the field combinations unique (as displayed in his example). If you want to prevent a duplicate in either column separately, then make then unique individually. In phpmyadmin simply go to the structure tab for the table and click the unique icon on the right side for each column.
-
DeCarlo, no need to pm me to ask a question regarding a response I have made in your thread. Just ask your question in the thread. Anyway, the process of implementing what I suggested above is very simple. When you register the person you would have to store their information some where. I will assume you are using a database. In that database you simply create a field to store the template the user selected during the registration process. You can either store the actual file name of the template they chose or create a table in the database for the template info and then you would store the ID of the template they chose. There are benefits and drawbacks to both methods. Then when the user logs in you can retrieve their selected template from the database and store the name in a session variable. Then use that session variable wherever you need to use the template.
-
I disagree. Let the user choose their template from a list of available templates and store the selection. Then you can dynamically include() the correct template at run time. No need to copy identical files all over the server.
-
The above function has a bug that will generate an error if the input is less than the length. This should work (tested): function maskString($inputStr, $showLen, $replaceChar='*') { $inputLen = strlen($inputStr); if($inputLen < $showLen) { return $inputStr; } $strIdx = ceil(($inputLen-$showLen)/2); $showStr = substr($inputStr, $strIdx, $showLen); $outputStr = str_repeat($replaceChar, $inputLen); return substr_replace($outputStr, $showStr, $strIdx, $showLen); }
-
Hard to say. It definitely isn't the most efficient structure. You will find a big benefit from separating your logic (core PHP code) from the presentation (HTML & CSS). In the case of what you are trying to achieve, I would make a determination if tehre were results to display or not, then include() the display page. If there were errors (i.e. "No news entries were found...") I would assign those errors to a variable. Then if there were errors or if the form was not submitted I would include() the form page which would have a small section to display the error if there was one. As to your specific problem. I would strip the entire page down to nothing more than a simple form, submit it and check the $_POST data. There could be something in the included header/footer pages that is causing a problem. Another tip. When developing do one thing at a time, test/check the results, then move on to the next thing. When you try and develop many different steps at once and run into a problem you don't know what is causing the problem
-
Well, what debugging have you done and what were the results? This is programming 101. If you are not getting the results you expect, then you need to add some debugging code to the page to "see" what the data is so you can check if the data is what you expect it to be. Is the page named "search_archive.php" as you have specified in the action parameter of the form? Did you put a print_r($_POST) at the top of the page to verify what POST data is sent? Have you "viewed source" on the page to verify what HTML code, if any, is actually there? FYI: You aren't creating valid HTML pages. That is very poor practice. It is not hard to build code that will output a complete, valid HTML page for any of the success/error conditions.
-
How can adjust this code to account for daylight savings time?
Psycho replied to bschultz's topic in PHP Coding Help
OK, after looking at the output I assume your issue is that you are getting 10-30 twice in the results. That is because you didn't specify an hour in your seed timestamp - so the start timestamp is set to midnight. Then, when you go forward 24 hours over the day where we "fall back" you are at 23:00 (11PM) of that same day. The solution is simple set your seed timestamp in the middle of the day. $str = 'last sunday 12PM'; -
How can adjust this code to account for daylight savings time?
Psycho replied to bschultz's topic in PHP Coding Help
What, exactly, is it you are having a problem with. How is it "not working' and how do you want it to work differently? -
Yeah, use mktime() - much faster than strtotime(). I would suggest a loop and storing the results in an array, but with what you had above this would work $monthInt = intval(date('n')); $yearInt = intval(date('Y')); $month = date('F d Y H:i:s', mktime(12, 0, 0, $monthInt-1, 1, $yearInt))."<br>\n"; $month1 = date('F d Y H:i:s', mktime(12, 0, 0, $monthInt-2, 1, $yearInt))."<br>\n"; $month2 = date('F d Y H:i:s', mktime(12, 0, 0, $monthInt-3, 1, $yearInt))."<br>\n"; $month3 = date('F d Y H:i:s', mktime(12, 0, 0, $monthInt-4, 1, $yearInt))."<br>\n"; $month4 = date('F d Y H:i:s', mktime(12, 0, 0, $monthInt-5, 1, $yearInt))."<br>\n"; $month5 = date('F d Y H:i:s', mktime(12, 0, 0, $monthInt-6, 1, $yearInt))."<br>\n"; Note, that if the result of $month-x is a negative value it will calculate correctly. So, January (1) with a -2 will result in November.
-
Right, when you set the action of the form, the form data is sent to that page (in this case PayPal). When you leave the action parameter blank the page posts to itself. That is why you can access the data when you leave the action blank. As stated previously, you will need to post the data to one of your pages, process it and rePOST to PayPal.
-
Um, I think one of is confused here and I'm not sure if it is me or you (but I'm thinking the latter). You originally stated that Now you state that Your action attribute is: action="https://www.sandbox.paypal.com/cgi-bin/webscr" When you use that action, your form is submitting to Paypal - not to your site. You would never see the POSTed data. You would need to POST the form to a page of yours so you can use that data to update your records and then re-post the data to paypal.
-
How do you know it is not posting? You are submitting the data to a paypal page so chances are you are not submitting the data in the manner it expects and is simply not processing the data. You should follow up with the Paypal documentation or support forum. If you can confirm that the form data is POSTed when submitting to your own page, then the data is POSTed. So, the problem is with how that POSTed data is accepted/used.
-
removing duplicate entries in a 2 dimensional array
Psycho replied to Yure's topic in PHP Coding Help
You still have not shown even one line of code. You know you need to iterate through he array so you should at least have a foreach() loop, right? Then add some code to test the data or repopulate into another array depending on the approach you are taking, then add the next step. Simply break down the solution into multiple steps. Then implement each steps and test that it works before adding the next step. -
The only thing I can think of is probably a pretty inefficient solution, but you'll have to see if it meets your needs with respect to performance and scalability. The idea goes something like this: create a dynamic table of all user ID pairs (concatenated), then select from that table any pair which does not exist in the current pairs (concatenated) from the selections the user has made previously. NOTE: I have not tested any of the following since I don't have the test database I used before and I'm not going to take the time to re-build it. I am going to provide the step-by-step portions so you can test as needed. So, working from the beginning, this query should give you a result of all "unique" user ID combinations. SELECT u1.userID AS id1, u2.userID AS id2 FROM `users` AS u1 JOIN `users` AS u2 ON u1.userID < u2.userID So, if you have four user ID: 1, 2, 3, 4 that should return the results: 1-2, 1-3, 1-4, 2-3, 2-4, and 3-4 The next step is to select a value from the result above where the same pair does not exist for a previous selection. But, the win/lose columns are not in order of smallest to highest, so we will need to get a little creative. So, this query should give you all the pairs that the user have previously compared in the same format as above. This query should get you all the user iD pairs for a particular user SELECT CONCAT(IF(win<lose, win, lose), '-', IF(win<lose, lose, win)) as userid_pair FROM `battles` WHERE `voter` = '$thisUserID' Now, we need to put those two queries together such that we want to select a value from the first query that does not exist in the second query. Again, this is not tested, but give it a go. SELECT u1.userID AS id1, u2.userID AS id2 FROM `users` AS u1 JOIN `users` AS u2 ON u1.userID < u2.userID WHERE CONCAT(u1.userID, '-', u2.userID) NOT IN ( SELECT CONCAT(IF(win<lose, win, lose), '-', IF(win<lose, lose, win)) as pair FROM `battles` WHERE `voter` = '$thisUserID') ORDER BY RAND() LIMIT 2 OK, I lied. There was a problem with my first approach, so I had to change it. So, I did test this and it works. But, again, not sure if there is a more efficient method or not.
-
So, what exactly is the problem. What is it you want to happen and what is is doing differently? By the way, that is some crappy JavaScript code. You should programmatically determine the days in the month to avoid problems with leap years.
-
Although thorpe didn't state it explicitly, he was trying to allude to the fact that the reason for the error is that the query is failing - not that there were no results. Simply doing a mysql_num_rows() on a failed query will generate the same type of error. That error would not occur if the query succeeded with 0 results.
-
The short answer is no. The database doesn't do anything "automatically" - you need to tell it what to do. But, creating a process to do all that is a fairly simple task. One function that you may not be aware of that makes this easy is mysql_insert_id() which will return the unique ID of the last inserted record. So, right after you INSERT the record into the 'document' table you can set $docID as follows $docID =mysql_insert_id(); you can then use that variable in the subsequent INSERTS that need that foreign key.
-
removing duplicate entries in a 2 dimensional array
Psycho replied to Yure's topic in PHP Coding Help
Or just use array_intersect_key()