
Psycho
Moderators-
Posts
12,164 -
Joined
-
Last visited
-
Days Won
130
Everything posted by Psycho
-
MSSQL If select returns row then run update sql statement
Psycho replied to kat35601's topic in PHP Coding Help
A page cannot output content to the page (even the tags that start the page: <html>, <head>, etc.) and then use a header command (such as a redirect). -
MSSQL If select returns row then run update sql statement
Psycho replied to kat35601's topic in PHP Coding Help
Why are you going to output content to the page AND THEN also have a redirect at the end (which will fail anyway since you've already output content to the page).? But, you don't need to do TWO queries. Just run the ONE update query since it already has the same condition as the first query. So the record would only be updated if meets the criteria anyway. -
Your explanation isn't very clear. It might help to show some sample data in those two tables and the expected results from the query.
-
Ch0cu3r meant to say "storing whether each member is subscribed or not in separate text files is very inefficient."
-
Well, you are using an INNER JOIN (or just JOIN) in a way by including both tables and using this in your WHERE clause WHERE o.orders_resellers_id = r.resellers_id Personally, I never use that type of construct to get data from associated tables. I would always use a proper JOIN for many reasons. For one it makes the criteria for associating the records much more apparent. Plus there are many features you can't use without a proper JOIN. Your original query would work the same as this FROM orders AS o JOIN r.resellers AS r ON o.orders_resellers_id = r.resellers_id The normal JOIN will return a result set for all records where a JOIN can be made. In this case, if there are any records in orders that does not have at least one corresponding record in resellers OR if there are any records in resellers that do not have a corresponding record in orders they will not be returned. In this case, you want ALL the records from the orders table even if there are no records in the resellers table. Based on the current query structure you would use a LEFT JOIN. That means return ALL matching records from the LEFT table (i.e. first table - orders) and JOIN any matching records from the right table (resellers). $sql = "SELECT o.orders_id, o.cust_order_id, o.cust_company, o.due_date, o.product, o.quantity, o.price, o.requirements, o.cust_order_total, o.order_status, o.reseller_earnings, o.orders_resellers_id, r.reseller_name, r.reseller_surname FROM orders AS o LEFT JOIN resellers as r ON o.orders_resellers_id = r.resellers_id ORDER BY due_date DESC"; Take a look at this page for some examples of JOIN types: http://www.sitepoint.com/understanding-sql-joins-mysql-database/ Also, I see you named the foreign key in the orders table as "o.orders_resellers_id". I would suggest naming it "o.resellers_id" - exactly the same as it is in the resellers table. That makes it explicit that it is a primary/foreign key in those two tables. Plus, as stated previously, there are some features where using the same name simplifies the logic: e.g. USING(). You could use this for example FROM orders AS o LEFT JOIN resellers as r USING(resellers_id)
-
I would create an index.php file that is used for all the requests. That file would have something like this at the top session_start(); //Check if family data is already set in session if(!isset($_SESSION['family'])) { //Set the default data include('setDefaultData.php'); } The setDefaultData.php page would have the initial data to set in the session. Something like this $family = array( //Include all the associative array data to set for the default ); $_SESSION['family'] = $family; As for how I would do it, I am the wrong person to ask. I don't have a formal education in programming and your instructor is looking for the use of specific design patterns.
-
Regarding the data, it doesn't state if the data needs to persist across sessions. You could just create an associative array (or arrays) with the starting state of all the data. Then on the first page load check to see if that data exists in the session. If not, load the initial data. Then on each subsequent page load use the session data. Then, whatever functionality you have will manipulate the session data. If you closed your browser and go back, you would start with the initial seed data. This is a good approach for an activity such as this for several reasons. You can create specific use cases that start with the initial data. As you test, if a problem is found you can modify the code and start the user cases over from the beginning. If you were to use a database you would likely need to reset it to default data anyway. As for the classes to you - that is up to you. How it should ideally be set up for this exercise would likely be predicated on any lessons you've already had in the class as lessons are typically designed to build upon the previous lessons.
-
When you say "on click" that typically means using the onClick event in JavaScript. But, based on your explanation, it could just as easily be accomplished with a normal HTML form. But, those are just two methods to initiate the action (i.e. make a call to the server). So, you can either use a traditional HTML form or use an onClick event to make an AJAX call. I would suggest starting with an HTML form to get a working solution, then you can add an onClick event to initiate if you need to perform it without a page refresh. I assume you would have a form with all the relevant files listed and perhaps checkboxes to indicate which files to be moved. You would submit that form to the processing page (PHP) which would take the form data with the list of files and perform a move operation on them. However, allowing user input to be used to perform low level file operations can be risky. You will need to ensure that all input is validated and ensure no malicious references are sent from the user. That is a very high level generalization. If you want more specific help, you will need to provide the specific part that you are stuck on.
-
Just to add to cyberRobot's response. If you reference the values in the result set in an associative array, there can only be 'one' value for any specific key in the array. So, you either need to alias different fields that use the same name or you can reference the data with a numerically based index. I would go with the former as cyberRobot suggests. Also, if you have such a problem, that might be an indication that you need to use more unique names (e.g. order_id & resellers_id). This way, you can use the same field name as the primary key in one table and the foreign key in another. It may seem more "wordy" and superfluous, but your queries will be much easier to read when you have many JOINs. Also, there are some MySQL functions that you can't use otherwise, such as USING()
-
AJAX makes sense in this situation because the other solution would require duplicate logic to be crated in JavaScript. That only makes things more difficult and error prone. Since you already have to create server-side code to do the calculation, you can just use AJAX (JavaScript that would call the server-side code) to get the same results. That way you only need to write the logic one-time and then re-purpose it for multiple uses (one to provide immediate feedback to the user and two to do the official calculation when processing the order). But, if the problem was about validating that a required field had a value it might be easier to write separate logic for server-side and client-side. As for how to implement AJAX, that is beyond the scope of a forum post. but, JQuery makes it very simple. Here is how I would implement it: 1. Create a file with a function to perform the calculations based on data passed to it. Typically this would be a list of products and quantities. The logic would look up the prices from the DB and do the multiplication and addition to get the subtotal. Then there might be additional logic around shipping or, in this case, comissions. The function would return the results. 2. The page that receives the form POST will process the data into the format expected by the function and then get the total for use in creating the order records. 3. Create another page to receive the AJAX request. That page would only need to format the POST data to send to the function and get the total. Then that page would return the total to the calling AJAX function 4. Create a trigger on the page to get the total (without the user actually submitting the order). The trigger would call a JavaScript function to send the relevant form field data to the page on #3 above.
-
You should NEVER rely on JavaScript (or anything client-side) for any business logic as it is very simple for a user to circumvent and pass whatever data they want. For example, if you have a select list of valid values for a particular field, you cannot assume that other values will not be passed. A malicious user can easily inject any value they want - regardless of what is in the select list. As to the above, if you were to rely on calculations made on the client-side to be used for the actual billing/charging of the customer, a malicious user could manipulate the values to anything they want. That is not to say that you can't add business logic to client-side code to provide the user a better experience. You just can't rely upon it. So, you would first want to ensure you have all business logic implemented on the server-side. Then, you can add logic on the client-side where it makes sense. For example, let's say you have a field for an email address and you want to validate that the format of the value matches what an email address should look like. You would add logic on the server to check the format and throw an appropriate error if found to be invalid. But, maybe you don't want to have the user POST the page before finding out such an error exists. You could then add additional client-side logic to check the email address when the user exist the field or when they attempt to POST. So, going back to the calculation. As stated above, you absolutely want to have server-side logic to do the calculations when it comes to billing/charging. If you want to give the user some immediate feedback, you could add client-side logic to do the same calculation. But, that can be a problem as you would have to ensure the two processes are in sync. Otherwise, you risk the displayed (client-side) value not matching what the user is ultimately charged. A better approach would be to write the logic one-time on the server-side. That process could be used for both the final calculation when the order is submitted and you could use it within an AJAX call to provide the user a total without having to POST the page. Just don't get that total to display in the client and populate a field for the purpose of using it when the user submits the page as they can change it (even if it is a read-only field). You will want to call the same logic to calculate the price when the order is submitted.
-
Wow. You must have a very interesting interview process.
-
You do order calculations on the client-side? Let me know what you are selling and I'll go buy mass quantities and 'hack' the price to be $0.01 I'm not sure what 'earnings' have to do with an order. But, if there are properties of the reseller (which can change) that affect the order, then that is data that is order specific and should be copied to the order as you say you are. Or, you can keep a historical record of those properties of the seller and reference the correct dataset when an order is placed. But, I don't know where this discussion started. If this is a response to my third point - my comments still stand. You are grouping the records to get the total which would prevent the data for those fields to be worthless. Then you can change the LEFT JOIN to a normal JOIN and those resellers without any matching records in the orders table will not be in the result set Then you don't need to SELECT the fields from the order table nor do you need to do the SUM() function (unless it is possible for orders to have a zero value for the reseller earning. If that is the case, then you would need the sum and the WHERE clause could exclude the records with a zero SUM value. And with respect to Barand's last post. If you are wanting all orders rom a specific date to today, then why not just use WHERE orders.due_date >= '2014-01-01' As he said, there shouldn't be any orders in the future.
-
One other note. The BETWEEN operator may not be working as you intend. When you have this due_date BETWEEN '2014-08-14' AND '2015-08-14' It will match all records starting at midnight (00:00:00) on 2014-08-14 to midnight (00:00:00) on 2015-08-14. In other words, anything on 2015-08-14 from 00:00:01 to 23:59:59 will NOT be included. Never mind. The due date is a DATE type and not a TIMESTAMP. So it will be inclusive.
-
A few thoughts. I create my queries in a logical order based on how you want the data. In this case you are gathering data about resellers with the earnings being secondary. So, I would select from the resellers table first. It would work with what you have, but it makes more sense to me to switch it. Second, what if there are not records in the orders table for a particular reseller. Using a normal JOIN, as you have above, that reseller would not be included in the results. If you want ALL the resellers to be displayed (even if there are no order records to JOIN on), then you need to use a LEFT/RIGHT join. You would use a RIGHT JOIN with the order you have above, but it would be a LEFT JOIN if done in the reverse order (which makes more logical sense to me). Third, you are including other fields in the order table (besides the earnings field). But, you are grouping the records from that table to get the total. I would assume each order has a unique ID, status and earning value. So, including those fields and doing a GROUP BY will retain only one value from one of the fields that were group. This makes no sense. Either leave those fields out or include them and leave out the GROUP BY to get the total - you can get the total by adding the earnings field when processing the records. But, I'm guessing you really don't need those fields. Fourth, ideally you would not be using a textual value for Order Status and instead use a numeric identifier (which could map to another table with the textual values). Using a LIKE clause to filter the records is very inefficient. Lastly, the SELECT list contains the field r.reseller_id, which does not exist. Based on the table schema provided it would be r.id Try this: SELECT r.id, r.reseller_name, r.reseller_surname, r.reseller_email, r.reseller_phone, r.reseller_commission, r.reseller_vat_number, -- o.id, o.reseller_earnings, o.order_status, SUM(o.reseller_earnings) as total FROM resellers as r LEFT JOIN orders as o ON r.id = o.resellers_id WHERE o.due_date BETWEEN '2014-08-14' AND '2015-08-14' AND o.order_status LIKE '%Order Completed%' GROUP BY r.id ORDER BY total DESC
-
Is it possible to see the result of left join of two tables?
Psycho replied to colap's topic in MySQL Help
What do you mean by "Is it possible to see the result of left join of two tables(without on clause)?" What do you expect to get without an ON clause for a LEFT/RIGHT JOIN? Why don't you explain what you are trying to achieve? -
Well, scootstah's 'creative' solution aside, both mine and Barands's solutions would work. If you review those two you would answer your question above.
-
The following solution protects against an item not existing in the list, but does not contain logic to prevent an infinite loop if the values were to contain such a problem <?php $paths = array( 'A' => 'B', 'B' => 'C', 'C' => 'D', 'D' => 'A' ); function getPaths($fullStart, $fullEnd, $paths) { $pathListAry = array(); //Return array $pathStart = $fullStart; //function var $pathEnd = false; //function var while($fullEnd != $pathEnd) //Run loop until full end is found { if(!isset($paths[$pathStart])) { echo "Error: No path starting with $pathStart"; return false; } $pathEnd = $paths[$pathStart]; $pathListAry[$pathStart] = $pathEnd; //Set start to current path end point $pathStart = $pathEnd; } return $pathListAry; } //Run solution $start = 'A'; $end = 'D'; $thePaths = getPaths($start, $end, $paths); //Output results echo "Starting from $start and ending at $end : <br><br>\n"; echo "<pre>" . print_r($thePaths, true) . "</pre>"; ?>
-
I've never used getElementByID() recursively like this var mname = document.getElementById('addform').getElementById('machine_name'); Is there a reason why you are referencing the form using getElementById() then trying to reference the 'machine_name' elements using getElementById() from that? Why not just directly reference the 'machine_name' element using var mname = document.getElementById('machine_name'); Also, the function doesn't make sense. You are getting the value for Target, but then simply returning returnVal - which is false. I'm guessing this is not complete. And, there will also be a failure on this line since 'f' is not defined var target = f.getElementById('target').value;
-
Except Barand hasn't posted in this thread . . . so I assume you are talking about the code I posted. Vapor, you posted a problem and we took the time to provide solutions. Now you are asking us to analyze some other code to determine what is better and "clean & secure". Sorry, but I'm not going to take the time to do that. The code I posted works with the content on the page provided at the time I wrote it. If that content changes (specifically the format), I can make no guarantees. As to how you should display the output, that I leave to you. That is where you definitely need to worry about ensuring the code will not create security problems (e.g. XSS). That can be resolved using htmlentities() as one solution. But, how you create the output (CSS tables, etc.) is up to you. This forum is about helping people with code they have written. It would be nice to see you at least make an attempt as opposed to just writing everything for you.
-
Here's a function to extract the data that appears to work for the data. You can then iterate through the array to create the content that you wish <?php function getData($url) { $output = array(); $content = file_get_contents($url); $lines = preg_match_all("#<a[^\n]*\n#", $content, $matches); foreach($matches[0] as $line) { if(preg_match("#<a[^>]*>([^<]*)</a> \"([^\"]*)\" \(W\) GUID\=(\d*)[^\[]*\[([^ ]*) ([^\]]*)#", $line, $match)) { $output[] = array( 'id' => $match[1], 'image' => "{$url}pb{$match[1]}.png", 'username' => $match[2], 'guid' => $match[3], 'date' => $match[4], 'time' => $match[5] ); } } return $output; } $url = "http://74.80.133.251/7778/"; $data = getData($url); echo "<pre>" . print_r($data, 1) . "</pre>"; ?> Here is an example of part of the output Array ( [0] => Array ( [id] => 001646 [image] => http://74.80.133.251/7778/pb001646.png [username] => -=D3G=-RotGM [guid] => 00000000000000076561198133386615 [date] => 2015.06.25 [time] => 17:20:36 ) [1] => Array ( [id] => 001647 [image] => http://74.80.133.251/7778/pb001647.png [username] => -=D3G=-Icey842 [guid] => 00000000000000076561198091035675 [date] => 2015.06.25 [time] => 17:22:18 ) [2] => Array ( [id] => 001648 [image] => http://74.80.133.251/7778/pb001648.png [username] => budsanonymous [guid] => 00000000000000076561198188792511 [date] => 2015.06.25 [time] => 17:23:28 ) Note that using RegEx is not very efficient. So, you may want to cache the data and only update if the cache is older than some time period.
-
Depends, how many users do you expect to have the chat window open at any one time? What kind of server/infrastructure will you be using? For example, a shared server will not be able to support as many users as a dedicated server. But, let's be real here. I don't know what project you are working on. But, you are not going to go out with something and have a milling people logging in the next day. A 2 minute wait will be sufficient for whatever you are building right now and the probably users you will have. If and when it becomes an issue, you can tweak the process to check for updates to be more robust. As long as you write good, modularized code making such an update would be simple.
- 10 replies
-
I see a lot of people running queries in loops - those are sure to kill performance. Here is what I would suggest: Create an array of values to measure the load time at specific points in the page creation. Then output the results so you can see how long each step in the process takes. Here is a quick example <?php $timings = array(); $timings['start'] = microtime(true); //Code to load include files goes here $timings['load_includes'] = microtime(true); //Code to run some DB operations $timings['run_db'] = microtime(true); //Code to build the page $timings['build_page'] = microtime(true); //Page execution done, create output to show times to complete each step $last = false; foreach($timings as $processDesc => $timing) { if($last != false) { $processTime = $timing - $last; echo "{$desc}: {$processDesc}<br>\n"; } $last = $timing; }
-
Are donations to specific users okay?
Psycho replied to Monkuar's topic in PHPFreaks.com Website Feedback
Do you need my paypal details? -
Several issues in that code: 1. You should not use 'external' variables to create a while() loop. Use a while() loop to get one row at a time. Makes the code much, much simpler. What you have now could easily break if the values for $i or $j get modified incorrectly. Not to mention that variables with names like $i and $j provide no context as to what they hold. 2. No reason to call mysql_result() many times instead of just calling a mysql_fetch_ one time. As to your question it can be implemented many ways. You can create ONE form and have a submit button for each record which will pass the ID of the record to your edit page. Or, you can make a mini form for each record. Which one you go with will be determined by several factors. You also need to decide what 'value' is passed to the edit page (I'm assuming it is the fkey). Here is one example: <?php require('connect.php'); session_start(); $query = "SELECT fkey, projectid, paying, completionmonth, completiondate, personspecify, projecttitle, categories, tools, shortdescription, date, time FROM project WHERE projectstatus='Open'"; $result = mysql_query($query); $count = 0; $projectList = ''; while ($row = mysql_fetch_assoc($result)) { $count++; $projectList .= "<br>{$count}<br>\n"; $projectList .= "<br>{$row['projectid']}<br>\n"; $projectList .= "<br>{$row['fkey']}<br>\n"; $projectList .= "<br>{$row['paying']}<br>\n"; $projectList .= "<br>{$row['completionmonth']} month {$row['completiondate']} days <br>\n"; $projectList .= "<br>{$row['personspecify']}<br>\n"; $projectList .= "<br>{$row['projecttitle']}<br>\n"; $projectList .= "<br>{$row['categories']}<br>\n"; $projectList .= "<br>{$row['tools']}<br>\n"; $projectList .= "<br>{$row['shortdescription']}<br>\n"; $projectList .= "<br>{$row['date']}<br>\n"; $projectList .= "<br>{$row['time']}<br><br><br><br>\n"; // I want to insert edit button here but dont know how $projectList .= "<form action='edit.php' method='post'>"; $projectList .= "<input type='hidden' name='fkey' value='{$row['fkey']}'>"; $projectList .= "<button type='submit'>Edit</button>"; ec$projectList .=ho "</form><br>\n"; } ?> <html> <head></head> <body> <?php echo $projectList; ?> </body> </html>
- 4 replies
-
- php
- formbuttons
-
(and 1 more)
Tagged with: