Jump to content

DavidAM

Staff Alumni
  • Posts

    1,984
  • Joined

  • Days Won

    10

DavidAM last won the day on December 2 2022

DavidAM had the most liked content!

About DavidAM

  • Birthday 05/23/1961

Profile Information

  • Gender
    Male
  • Location
    Spring, TX USA

Recent Profile Visitors

11,483 profile views

DavidAM's Achievements

Member

Member (2/5)

128

Reputation

1

Community Answers

  1. I would think that would work. Make sure you are casting to an numeric value (Integer) so the Order by is sorting numerically, not be string values.
  2. I don't know Postgresql. The problem you're going to have is that 1.10 is less than 1.9, In fact, it is equal to 1.1. If the Cast-Substribg works (again, I don't know Postgres), you should do it twice to split the version number. And order by the two values. Something like this CAST ( SUBSTRING ( movies.title FROM '#(\d+)\.\d+' ) AS INT ) AS major, CAST ( SUBSTRING ( movies.title FROM '#\d+\.(\d+)' ) AS INT ) AS minor ... ORDER BY major, minor You can use Integer now, instead of Decimal.
  3. Please use the code tags - the "<>" in the formatting bar. It makes the code easy to read and work with. You need to capture the index of the child you add in LOOP 2 and use that index to add the children in LOOP 3 # LOOP TWO # ... $data1 = array('id' => $row1['id'], 'name' => $row1['name'], 'title' => $row1['title'] , 'relationship' => '111'); $data_cst["children"][] = $data1; $index1 = count($data_cst["children"]) - 1; // <== ADD THIS LINE # LOOP THREE # ... $data2 = array('id' => $row2['id'], 'name' => $row2['name'], 'title' => $row2['title'] , 'relationship' => '111'); ## ????????? // CHANGE THIS TO $data_cst["children"][$index1][] = $data2; Running queries inside a loop is generally not a good idea. If you know you are going to go 3 levels (or some other fixed number), you can do this all with a single query and then build your array. Also, do not select everything from the table. Select only the columns you want/need. You might try something like this. I have not tested it, but I think it will come close. <?php require_once 'pdo.php'; $data_cst = array(); // FIRST LOOP try{ $sql = 'SELECT L1.id AS L1id, L1.name AS L1name, L1.title AS L1title, L2.id AS L2id, L2.name AS L2name, L2.title AS L2title, L3.id AS L3id, L3.name AS L3name, L3.title AS L3title FROM main AS L1 LEFT JOIN main AS L2 ON L2.parent_id = L1.id LEFT JOIN main AS L3 ON L3.parent_id = L2.id WHERE L1.level = 0'; $result = $pdo->query($sql); if($result->rowCount() > 0){ while($row = $result->fetch()){ $L1id = $row['L1id']; if ( ! isset($data_cst[$L1id])) { // If this is the first row for the L1id, create the data for it $data_cst = array('id' => $row['L1id'], 'name' => $row['L1name'], 'title' => $row['L1title'] , 'relationship' => '001', 'children' => []); } if ( ! empty($row['L2id'])) { // We have data for a child of L1id $L2id = $row['L2id']; if ( ! isset($data_cst[$L1id]['children'][$L2id])) { $data_cst[$L1id]['children'][$L2id] = array('id' => $row['L2id'], 'name' => $row['L2name'], 'title' => $row['L2title'] , 'relationship' => '111', 'children' => []); } if ( ! empty($row['L3id'])) { // We have data for a child of L2id $L3id = $row['L3id']; $data_cst[$L1id]['children'][$L2id]['children'][$L3id] = array('id' => $row['L3id'], 'name' => $row['L3name'], 'title' => $row['L3title'] , 'relationship' => '111'); } } } } else { echo "No records matching your query were found."; } } catch(PDOException $e){ die("ERROR: Could not able to execute $sql2. " . $e->getMessage()); } echo json_encode($data_cst); Notes: Don't bother closing query results or the database connection. PHP will handle it when the script ends I indexed the "children" array with the associated ID instead of letting PHP assign something. This made it easier to add the next child or sibling
  4. I just thought it would be good to explain why the original calculation was not working.
  5. Your math is off. There are 1,000 mm in a meter. But there are 1,000,000 square mm in a square meter. You should divide by 1,000,000 if you use the approach in your original post. 900mm * 1500mm / 1000000 = 1.35 sq meters
  6. My guess is your XAMP configuration is pointing to the wrong folder for Document Root. Looking at your File System image, I see a folder named "public". This is often the name of the document root. Perhaps your AMP configuration is pointing to SchoolApp-master when it should be pointing to SchoolApp-master/public. In the public folder there should be an index.php file and a .htaccess file. There is probably also a folder in there called auth.
  7. I found it puzzling, too. I was too lazy to try from the database, but this is interesting: <?php error_reporting(-1); ini_set("display.errors", 1); /* Test string indexes in array: http://forums.phpfreaks.com/topic/301470-notice-undefined-offset-2013/#entry1534467 */ printf('PHP Version: %s' . PHP_EOL, phpversion()); printf('uname: %s' . PHP_EOL, php_uname()); echo PHP_EOL; $res = array( array( 'Row' => 'First', (string) 2013 => 30.5, '2014' => 42, "2015" => 8 ), array( 'Row' => 'Second', (string) 2013 => 11.5, '2014' => 42, "2015" => 6 ), ); foreach($res as $row) { printf('%6s: %.2f %d %d' . PHP_EOL, $row['Row'], $row['2013'], $row['2014'], $row['2015']); printf('%6s: %.2f %d %d' . PHP_EOL, $row['Row'], $row["2013"], $row["2014"], $row["2015"]); printf('%6s: %.2f %d %d' . PHP_EOL, $row['Row'], $row[2013], $row[2014], $row[2015]); printf('%6s: %.2f %d %d' . PHP_EOL, $row['Row'], $row[(string) 2013], $row[(string) 2014], $row[(string) 2015]); printf('%6s: %.2f %d %d' . PHP_EOL, $row['Row'], $row[strval(2013)], $row[strval(2014)], $row[strval(2015)]); echo PHP_EOL; } echo PHP_EOL . 'SERIALIZED: ' . PHP_EOL; echo serialize($res); echo PHP_EOL; echo PHP_EOL . 'VAR_DUMP: ' . PHP_EOL; var_dump(array_keys($res[0])); echo PHP_EOL; /* RESULTS PHP Version: 5.5.12 uname: Windows NT XXXXXX 6.1 build 7601 (Windows 7 Business Edition Service Pack 1) i586 First: 30.50 42 8 First: 30.50 42 8 First: 30.50 42 8 First: 30.50 42 8 First: 30.50 42 8 Second: 11.50 42 6 Second: 11.50 42 6 Second: 11.50 42 6 Second: 11.50 42 6 Second: 11.50 42 6 SERIALIZED: a:2:{i:0;a:4:{s:3:"Row";s:5:"First";i:2013;d:30.5;i:2014;i:42;i:2015;i:8;}i:1;a:4:{s:3:"Row";s:6:"Second";i:2013;d:11.5;i:2014;i:42;i:2015;i:6;}} VAR_DUMP: array(4) { [0] => string(3) "Row" [1] => int(2013) [2] => int(2014) [3] => int(2015) } */The different types of string quoting/coercing, makes no difference. PHP is implicitly converting the associative keys to integers. Which does not matter when I reference them because of the loose data-typing in PHP. My guess is that the database driver is setting the array keys (internal representation) as strings. The "solution" works (I guess) because the odbc->result() call expects a column name to be a string. The array reference (in the OP) was converted to an integer since that's how PHP (internally) handles them (when the key is composed of only digits). The other interesting thing is: var_dump() on this machine, would not dump $res. Or I should say, it produced array(2) { [0] => int(0) [1] => int(1) } I don't use var_dump() much - I usually use print_r() - unless I need to see the datatypes. So, maybe that's normal?
  8. The user's browser (all browsers) need an absolute url to request something from the Internet. When the browser gets a relative url, it uses the current page to determine the absolute url for the request. Since you are doing rewrites on the server side the browser thinks the current url is www.yourdomain/article/10/this-is-something, so it drops the "this-is-something" (because that's the "file" name) and keeps the rest as the "directory" name; then tacks the relative url on the end - so it has www.yourdomain/article/10/index.php. In short, change the relative urls, to absolute urls. You don't have to include the domain, just put a slash at the front: /index.php since that goes to the document root for the current domain.
  9. There are two things you need to change: $headers = 'From: '.$name.' <'.$email.'>'; // Change to $headers = 'Reply-To: '.$name.' <'.$email.'>'; Your server is (most likely) not authorized to send mail "From" whatever is in $email. Sending mail from "yourDomain.com" and saying it is from "someOtherDomain.com" will appear as a forgery and likely get you SPAM points (in this case the email with the fewest points, wins). Mail from your server needs to say it is from your server, and the server/PHP should be configured that way. The "Reply-To" header will allow the recipient to reply to the $email, which is probably what you are trying to accomplish there. mail($email_to, $subject, $message, $headers); $sent = true; // Change to $sent = mail($email_to, $subject, $message, $headers); You are arbitrarily saying the email was sent. mail() will return false if it cannot submit it to the sendmail system. That would be a server configuration issue. However, just because you get true from mail() does not mean the mail went out. It just means it was handed to the server's sendmail system. So, if this returns false, check the server's configuration. If it returns true, and you still don't get it, look at the sendmail configuration and (to some extent) the PHP configuration. Always check your Junk mail/Spam filters when looking for mail from PHP. It is possible there are headers missing or present that will get the mail flagged or discarded.
  10. What records do you think are duplicate? I don't see any. I see a Cartesian Product between the Infractions and Actions table. There is no relationship and no join between these tables, so every row for Student 7 in Infractions is associated with every row in Actions for Student 7. If an Action is not intrinsically associated with a specific Infraction, then you cannot report them that way. If they are associated, then the database design needs to be fixed. Concerning Student #7 ("ahmad") is Actions #1 ("Actions 1") associated with Infractions #1 ("infractions 1") or Infractions # 2 ("infractions 2")? Is Actions #2 ("Actions 2") associated with "infractions 1" or "infractions 2"? Your database design does NOT provide any relationship (association) other than the Student ID. So, all Infractions for Student 7 are associated with all Actions for Student 7 -- and that is EXACTLY what the output is telling you.
  11. There is no relationship between Actions and Infractions. Therefore all Actions (for a student) are associated with all Infractions (for that student) - a Cartesian product. The relation between Students and Infractions is one-to-many (one Student can have many Infractions). If a single Infraction can have only a single Action, I would eliminate the Actions table and put the Action_Text in the Infractions table -- leave it NULL until the action is applied. If an Infraction could result in one or more Actions (or you really want/need a separte table), the Actions table should be realted to the Infractions table NOT the Student table.
  12. @pwntastic I'm glad you asked the question. The short answer is: no, only the bound data (none in your example) is protected from SQL injection. DavidAM climbs up on his soap-box Prepared statements do NOT automatically protect you from SQL injections. And I wish people would quit suggesting them for that purpose. If we are going to suggest that, we may as well suggest turning MAGIC QUOTES back on!! It amounts to the same thing -- a false sense of security. The proof is in the OP's original question: Prepared statements are not about security. They were invented - years and years ago - for the purpose of improving performance on queries run in a loop. There are two stages of execution at the database server for a query. 1) Build the query execution plan; and 2) Execute the plan (with specific data). When it was necessary to execute a query in a loop, the "plan" for that query was built every time. Prepared statements were invented so the plan could be built once, and executed multiple times. I am NOT advocating queries in a loop. The RDBMS is built on Set Theory, and it will always be more efficient to execute a single query to affect multiple rows, when possible. But sometimes it is necessary to use a loop to execute the same query, with the calculations for the data being too complex or not available to put in a single query statement. For this we have Prepared Statements. Read the manual: http://us1.php.net/manual/en/mysqli.quickstart.prepared-statements.php (emphasis added) http://us1.php.net/manual/en/pdo.prepared-statements.php (emphasis added) When true server-side prepared statements are used, it takes two round-trips to the database. When a non-prepared statement is executed, it takes only one round-trip. Using prepared statements exclusively increases resource use. The PDO page also says: (emphasis added) The automatic quoting of the bound data is a side-affect of the prepared statement. And we need to clearly state that only the bound data is protected from SQL injection. Otherwise, we are giving a false sense of security; the same false sense of security that many PHP coders had when using magic_quotes - which has been removed from the language because of the false sense of security. DavidAM climbs off his soap-box
  13. When asking for help with a warning/error, you need to post the entire error message here. It will help us help you more quickly (and correctly). My guess is that $company['contacts'] and $company['branches'] are not arrays at the point that you get the warning. If you look closely at your collection code, when you first spot a company you don't include those sub-arrays in the company creation: if(!isset($company_array[$row['company_id']])) { //Add the company specific data here $company_array[$row['company_id']] = array( 'name' => $row['comp_name'], 'address' => $row['address'], 'phone' => $row['phone'], 'fax' => $row['fax'], 'web' => $row['web'], 'email' => $row['email'] , // Add these lines AND THE COMMA above 'contacts' => array(), 'branches' => array() ); In addition, during the branch collection you have a small logic error: $compID = $row['company_id']; $branchID = $row['branch_id']; // YOU SHOULD HAVE $compID in the first subscript - where you have '' if(!isset($company_array['']['branches'][$row['branch_id']])) { $company_array[$compID]['branches'][$branchID] = array( Also, since you grabbed the $compID and $branchID, why not go ahead and use them in that if statement?
  14. No, you cannot overlap or nest FORMs in HTML. If you need the quantity in both forms, and it needs to be the same value, you will need to use JavaScript. Put a hidden input field in the second form to hold the quantity. Then either (1) add an event (JS) to the other form's quantity field so when it changes, the hidden field is updated with the new value; or (2) and an onSubmit event to the paypal form to retrieve the current value from the other quantity field and put it in the hidden field (before sending).
  15. The <FORM> tags do not have any affect on the layout of the page. It is really just a container for form fields. You just need to move the opening tag above your first form field. Be aware, if there are other form fields on the page (not shown in the code you posted), they will become part of the form and will be sent when the form is submitted.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.