Psycho
Moderators-
Posts
12,157 -
Joined
-
Last visited
-
Days Won
129
Everything posted by Psycho
-
Hmm . . . I think you need to clarify this statement So, are you saying if the user enters "ABCD" you want to find any records that contain the letters "ABC", "ABD", "ACD" or "BCD"?
-
And I would follow that up with nl2br() to convert line breaks to <br> tags. Just be sure to do that after htmlspecialchars or else you will conver the br tags to textual content. EDIT: You did state you wanted to preserve 'spaces'. In which case PRE, as Kicken suggested, is the way to go. And if you do implement that, then you do not want to use nl2br(). Basically, there are several solutions and each has things it can and can't do. You'll need to determine exactly what you want to implement the best solution.
-
Just out of curiosity I decided to try and find a solution. It was much simpler than I thought. You would obviously need to have the "inventory" of the ATM with what denomination of bills are available and the quantities. Then you also have the requested amount. You simply need to loop through the available denominations from highest to lowest and determine how many of that denomination will "fit" within the requested amount and apply the minimum of that or the available quantity. You would also want a check at the end of the loop to determine if the requested amount was met (there may not be enough cash or the requested amount is not obtainable, e.g. $31). Here is a PHP solution. I made the $inventory a hard coded array for testing which would need to be dynamic.I also used global in the function (which I typically avoid) only for the purpose of brevity in the code - a class would probably be a better solution. <?php //Array pf possible denominations and their available qty $inventory = array( '50' => 3, '20' => 2, '10' => 5, '5' => 10 ); function getCurrency($requestAmt) { global $inventory; //Ensure inventory is from high to low denomination krsort($inventory); $distribution = array(); $newInventory = $inventory; foreach($newInventory as $denom => $quantity) { //Determine number of bill of this denom $denomQty = min($newInventory[$denom], floor($requestAmt/$denom)); //Update distribution and inventory $distribution[$denom] = $denomQty; $newInventory[$denom] -= $denomQty; //Reduce requested amount $requestAmt -= $denomQty * $denom; } //If unable to meet distribution, return error if($requestAmt != 0) { return false; } //Return distribution result (removing unused denoms) $inventory = $newInventory; return $distribution; } ################ ## TESTING LOGIC ################ $requestedAmounts = array(100, 32, 50, 25, 10, 50, 100, 20, 40); $header = "<tr><th></th>\n"; foreach(array_keys($inventory) as $denom) { $header .= "<th>\${$denom}</th>"; } $header .= "<th>Total</th></tr>\n"; foreach($requestedAmounts as $amt) { echo "<br><br><table border='1'>\n"; echo "<tr><th colspan='6'>Requested amount: $ {$amt}<th></tr>\n"; echo $header; displayCurrencyRow("Current Inventory", $inventory); $distribution = getCurrency($amt); if(!$distribution) { echo "<tr><td colspan='6'>Unable to fulfill request</td></tr>\n"; } else { displayCurrencyRow("Distributed Amount", $distribution); displayCurrencyRow("Remianing Inventory", $inventory); } echo "</table>\n"; } function displayCurrencyRow($label, $amounts) { $total = 0; echo "<tr>\n"; echo "<td>$label</td>\n"; foreach($amounts as $denom => $qty) { echo "<td>$qty</td>\n"; $total += $denom * $qty; } echo "<td>\${$total}</td>\n"; echo "<tr>\n"; } ?>
-
I'm actually curious if the original question asked is the "right" question. It only gave a couple of examples using $100 as the requested amount. Are those really the only scenarios? Or, is it really a more general question of "When requesting money the machine will dispense using the largest available denominations". In that case it is necessary to know all the denominations the machine contains and the possible amounts that can be requested.
-
Dynamic variables not geting values assigned
Psycho replied to michaelmoxley's topic in PHP Coding Help
Well, first of all that is a really bad way to get the data you want from a table. You should NEVER run queries within loops. And, in this case, there is a very, very easy solution. Just use your $lookup array to create ONE query with all the fields you want. I'll show you some code for that at the end. Also, with respect to your code, you would do yourself a great favor by giving your variables meaningful names. In the above example $value doesn't contain a "value" it contains the name/label/field of a value. It was kind of awkward reading the code for me. Also, your query has a LIMIT 1 on it but the processing logic uses a loop to get the records. That isn't needed. As to your question, it's difficult to say what the problem is. To be honest, I've never used a variable to the right of the 'arrow' for an object property $row->$value. But, I will assume it is valid. You don't show the rest of the foreach loop. So, if the value of $id changes in the loop it could be that the 2nd and 3rd iterations are not matching any records in the DB. $fields = array('id', 'last_name', 'email'); $selectList = implode(', ', $fields); $query = "SELECT $selectList FROM user WHERE id = $id LIMIT 1"; $result = mysql_query($query) or die ("Error in query: $query. " . mysql_error()); if(mysql_num_rows($result)) { $row = mysql_fetch_object($result); foreach($fields as $field) { echo $row->$field . ":" . $field; } } EDIT: muddy beat me to it, but I'll post this anyway -
Ok, I think you are making this more difficult than it needs to be. You can just make each button its own form and the button is a submit button. And in each of these forms create a hidden field that has the value of the record ID. Lastly, set the action of the form to the page where you want to redirect them and set the method of the form to GET. When the user clicks the button the form will send the form values (i.e. the hidden field) on the query string to the requested page. That page can then take that ID and perform the update you want to achieve. Alternatively, forget the button altogether and just create a "Reserve" link next to each record as a hyperlink with the ID already included in the URL of the hyperlink. based upon the new information, I think AJAX would be a waste for this solution.
-
Well, I say we take a step back first. You are trying to output a list of records and display a button next to each of them. Great, we got that. So, what - exactly - are you wanting to happen when the user clicks a button? Based upon the first post the user would get redirected to the same page no matter what button was pressed. I *think* you are wanting to let the user "reserve" multiple records on the same page by clicking multiple buttons without having to refresh the page. If that is the case you have two options: 1. Use AJAX. Trying to teach you thins in a forum post will not be productive. You can use frameworks (such as JQuery) to do a lot of the difficult part - but you will still need to do the work of how to implement this. 2. Forget about the multiple buttons. Give the user a checkbox next to each record and a button to submit the entire page and all their selections in one go.
-
best way of geting url form user and validate them...
Psycho replied to thara's topic in PHP Coding Help
I hid your post because it specifically referenced validation of email addresses, whereas this post is about URLs. I thought you jumped the gun and misread the request. Instead it seems you may have made a typo -
best way of geting url form user and validate them...
Psycho replied to thara's topic in PHP Coding Help
I think what you are asking is not so much a technical/programming problem as much as a best practice approach. In all the addresses you mentioned (Web Address, Facebook Address, Twitter Address, Google+ address) I believe all of them use just http, so https, ftp and others are probably not needed. You need to first make that determination - do you need to support protocols other than http? The answer to that question will be a factor in the appropriate path you take. If you do need to allow for other protocols it does become more complex. If you only need to support http, then you know the user may or may not enter the protocol as part of the address. So, I would first check the submitted value to see if the protocol was entered (look for //) and remove it. Or, you could check if it's not there and add it. The important thing is to make sure that the value you use in your processing is "normalized" to a certain format. If you need to support multiple protocols you could check if one was entered and, if it was, verify that it is a valid protocol. If no protocol was entered then I would assume it is http and use that. -
Nothing. The \d is the character class for digits Perhaps, but someone would only find that out after they already created their password on a PC and then later needed to log in on a mobile device. I'm not saying you should exclude characters only that there are some legitimate reasons for doing so.
-
In theory, I agree that you should not restrict what characters can be entered. But, in practice, there are legitimate reasons for doing so. If a user is normally on a PC with a keyboard setup that allows some "non-traditional" characters, that user may have problems logging when away from that computer - i.e. on the road. Similarly, and probably more importantly, many characters that can easily be entered on a PC are either difficult or impossible to enter from a mobile device.
-
That regex can be simplified. Since the lookaheads do not consume any characters, there is no need to put a lookahead at the beginning looking for 8 characters - simply do a length check at the end $RegExp = '/(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,}/'; However, in addition to checking for at least one of each character class that regex will allow any characters. If you want to restrict which characters are allowed as you may have been insinuating - then you will need to modify that length check to include all the required characters as well as put the begin/end bindings to ensure there are no errant characters. $RegExp = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d!@#$%^&*._-]{8,}$/'; ^ # Bind the RegExp to the beginning of the string. (?=.*[a-z]) # Anything, followed by at least one lowercase (non consuming) (?=.*[A-Z]) # Anything, followed by at least one uppercase (non consuming) (?=.*\\d) # Anything, followed by at least one number (non consuming) [a-zA-Z\\d!@#$%^&*._-]{8,} # All characters must be within this class and be 8+ in length $ # Bind the RegExp to the end of the string.
-
I don't think you have really thought this out far enough. Do you realize that the due dates will always be shifted to the 28th or earlier for all payments after February (leap year aside)? So, a user makes a payment on Jan 31st. In Feb, there are only 28 days, so you want the payment to be due on Feb 28th. Then the payment will be due on the 28th of every month thereafter. Or are you wanting the date to go back to the 31st (or the 30th) for months with more days? If so, how are you going to determine the difference between a due date that was originally set on the 28th vs. one that was originally on the 30th or 31st.
-
No. It is called mysql_real_escape_string() for a reason. $_GET/$_POST values are always string types. So,the input is already a string anyway. PHP is a "loosely" typed language. That means it can (usually) convert variables to the proper types as needed. So you can do math operations on string variables if they contain numeric characters. But, none of this means that you should not safeguard the user input from wreaking havoc on your queries. In this case you want the value to be an integer. So, use the functions within PHP to ensure it is an integer. You can force the value to be an integer by using the intval() function or typecasting the value as in integer $valueAsInt = intval($_GET['page']); $typeCastAsInt = (int) $_GET['page']; If the value cannot be converted to an integer value you will get 0. The other approach would be to validate that the value is a string that has the characters matching an integer value; if(!ctype_digit()) { //Value is not a proper integer - do something // - provide error or force to default value, e.g. 1 } else { $page = $_GET['page']; } I would typically do this //If post value is set, use intval of it, else default to 1 $page = (isset($_POST['page']) ? intval($_POST['page']) : 1; //Assuming I know the max page number //If page less than 1 or greater than max page default to 1 if($page<1 || $page > $maxPages) { $page = 1; }
-
What are you talking about? What "message"? Your original post stated: I provided examples of queries that will select from all the products that are not already in the cart. If you don't want users to "quick add" products that are already in their cart then don't provide those products for Quick Add. Making those products available only to have to provide an error message if they actually select it is kinda stupid in my opinion.
-
loop through days 1 - 28 and then start again 1 - 28
Psycho replied to brown2005's topic in PHP Coding Help
Here you go. You only need to modify the first three variables. I changed the output for verification purposes. Modify as you need it. $calendarYear = '2013'; $indexStart = 16; $indexMax = 28; $date = strtotime("1/1/{$calendarYear}"); $year = $calendarYear; $index = $indexStart - 1; echo "<table border='1'>"; echo "<tr><th>No:</th><th>Date</th><th>Day of Week</th></tr>"; while($year == $calendarYear) { $indexNo = $index % $indexMax + 1; $dateStr = date('m-d-Y', $date); $dowNo = date('w', $date); echo "<tr><td>$indexNo</td><td>{$dateStr}</td><td>{$dowNo}</td></tr>\n"; $index++; $date = strtotime("+1 day", $date); $year = date('Y', $date); } -
You can do this with a simple query - no need to select all the record and loop over them. For the products that are already in their cart you would obviously be storing this information somewhere AND that information should be based off the product ID. You just need to create a select query that uses the NOT IN condition with the list of product ids that are in the user's cart. I will provide two examples based upon how you might be storing the cart info. Cart info stored in a 'cart_prod' table. This assumes there is a carts table where the cart is associated with the user and the cart_prod table is for the products associated with each cart entry. SELECT prod_id, prod_name FROM products WHERE prod_id NOT IN (SELECT prod_id FROM cart_prod JOIN cart ON cart.id = cart_prod.cart_id WHERE cart.user_id = '$user' ) Or, if the cart is stored in a session variable. This assumes the cart is stored as a multi-dimensional array in the format $_SESSION['cart'][{PROD_ID}] = {QUANTITY} $cart_ids = impldode(',', $_SESSION['cart']); $query = "SELECT prod_id, prod_name FROM products WHERE prod_id NOT IN ($cart_ids)";
-
@us2rn4m2: Why would you want to create an elaborate process that uses regular expressions only to do simple string validations for which there are built-in PHP functions to do? Either create the more elaborate solution to use only "basic" functions and avoid RegEx completely OR use only a RegEx solution - which only requires a single line. Barand provided the first and Christian provided the second. Your solution is, to be perfectly honest, an attempt at a mishmash of the two which doesn't get any of the benefits (string functions are typically much faster than RegEx and RegEx alone can be done with much, much less code). Plus, as pointed out, it wouldn't work anyway. Although, I will say that I thought Christian's RegEx was a little more complicated than it needed to be. I would have written it out a little more plainly function validLicense($licenseStr) { return preg_match("#(\d{2}|[a-z]{2})-(\d{2}|[a-z]{2})-(\d{2}|[a-z]{2})#i", $licenseStr); } . . . but there would be benefits/drawbacks to either his or my solution. So, it's probably more of a preference.
-
Is there a built-in hasNext property when looping MySQL results?
Psycho replied to soycharliente's topic in PHP Coding Help
-- Deleted -- -
Is there a built-in hasNext property when looping MySQL results?
Psycho replied to soycharliente's topic in PHP Coding Help
Why store the result of mysql_num_rows() in a variable if it will only be used once? But to your question, I'm not really sure what you are asking. The PHP code you posted appears that it would only do a line break when completing all of the records of the result. So, not sure why you added all that complexity. What I *think* you are trying to do is insert a line break between what I would call "parent" records in the result. For example, if I did a query of an authors table and JOINed it with a books table I would expect to get multiple records where the author data is the same. So, I might want to put a line break between the records for each author in the output. The Velocity code you posted seems to be similar to processing an array in PHP - which can be done with foreach loops. But, databases do not have that kind of structure in the results (at least none of the ones I've used). But, the solution is pretty simple - just use a variable as a flag. if (mysql_num_rows($result)) { //Set flag to track changes in author $currentAuthor = false; echo '<p>'; while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) { printf("%s", $r['word']); //Check if this record has the same author as the last if ($currentAuthor != $row['author_id']) { echo '<br />'; $currentAuthor = $row['author_id'] } } echo '</p>'; } -
Well, I'm glad you were honest about this being homework. Many of us that are regular helpers hate it when we see a bunch of people posting the exact same question making it seem they are trying to get a solution to a real problem. We don't like to just give a solution to homework problems as it does nothing to help the person learn. So, when you have a problem such as the above. The best thing, in my opinion, is to first understand what the requirements are and ow you would do that process - without programming, i.e. as a human that was doing that validation manually. So, do you understand what would be valid license plates based upon the above requirements? The best solution I can think of would be the use of a regular expression, which I am sure is way beyond your capabilities. And, I am kinda confused by the tip to use modulo. I can't really think of a solution that would use that. There are a few other solutions I can think of to accomplish this, but not knowing what you do and do not know I'm not sure what to suggest. But, one would be to use explode() to convert the string into an array, then verify the contents of each element of the array. But, I don't want to give too much.
-
You think they contains numbers. If the variables would contain the values that would create a string that is the same as one you've hard-coded that works - then it would work with the variables. Also, don't try to do too many things in a single line as it makes debugging more difficult. Try the following $url = 'https://graph.facebook.com/' . $facebook_page_id . '/feed?access_token=' . $access_token; echo "URL: $url"; //Debug line $json_content = file_get_contents($url);
-
There is no way for us to tell you since we have no idea what those variables contain. Also. I assume you are getting an error, so what is it? In many cases an error is reported on a particular line, but the actual error is on a previous line. It's just not till the line in question that the PHP parser gets stuck.
-
I don't see why it would be showing only the participant data and not the registrant data. But, I'm not going to create a database to test it. Learn to debug code. But, I do see why it is appending the participants for each registrant. On the condition that tests for a a different $currentRegID the code needs to reset the $registrantData to remove the previous data. So, right before the line that sets the $currentRegID flan in the if condition you could put: $registrantData = array(); Having said that however, Barand's query would be much more efficient. Once you see the results from that you should be able to see how to implement the output.
-
This might not create the output exactly as you want it, but it should get you started <?php function registrantTable($regDataAry) { //Define paid status and make participant list comma separated $paid = (!empty($regDataAry['invoiceid'])) ? $regDataAry['invoiceid'] : 'no'; $participants = implode(', ', $regDataAry['participants']); //Create table for the registrant info $output = "<table>\n"; $output .= " <tr>\n"; $output .= " <td>{$regDataAry['name']}</td>\n"; $output .= " <td>{$regDataAry['phone']}</td>\n"; $output .= " <td>{$regDataAry['email']}</td>\n"; $output .= " <td>{$paid}</td>\n"; $output .= " </tr>\n"; $output = " <tr>\n"; $output .= " <td colspan='4'>{$participants}</td>\n"; $output .= " </tr>\n"; $output .= "</table>\n"; return $output; } $query = "SELECT r.id, r.name, r.phone, r.email, r.invoiceid p.participant FROM registrants AS r INNER JOIN participants AS p ON p.registrant_id = r.id WHERE event_id='{$_GET['id']}' ORDER BY r.id"; $result = mysql_query($query); if(!$result) { echo "Query failed"; } elseif(!mysql_num_rows($result)) { echo "There were no matching records."; } else { $currentRegID = false; //Flag to track when reg id changes $registrantData = array(); //Temp array to hold set of data for a registrant while($row = mysql_fetch_assoc($result)) { //Check if registrant ID has changed if($currentRegID !== $row['id']) { //If not first record display records for previous registrant if(count($registrantData)) { echo registrantTable($registrantData); } //Set flag for current registrant $currentRegID = $row['id']; //Set "base" data for the current registrant $registrantData['name'] = $row['name']; $registrantData['phone'] = $row['phone']; $registrantData['email'] = $row['email']; $registrantData['invoiceid'] = $row['invoiceid']; } //Append particant to current registrant data $registrantData['participants'][] = $row['participant']; } //Display records for last registrant echo registrantTable($registrantData); }