Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Phi11W last won the day on June 18

Phi11W had the most liked content!

1 Follower

Recent Profile Visitors

1,157 profile views

Phi11W's Achievements

Regular Member

Regular Member (3/5)




Community Answers

  1. Pull the data back out of the database and copy it into your favourite spreadsheet program (e.g. MS Excel). Then do the same with the data from the original file. Put the two lists side by side on a single worksheet, sort the two lists and compare visually. It shouldn't take more than a few minutes to find the ones that appear in one list and not the other. Regards, Phill W.
  2. If you're building an API, then it should be built and run on your own infrastructure (servers). If this is the case, then your Oracle database should absolutely not be exposed to the external network. Anything on your machine(s)? That can be trusted. (Mostly). Anywhere else to your machine? That's not trusted. Only the Web URL should be made available to the client and that will require you to have a Web server process (again, running on your infrastructure) that will receive those requests and process them as required. Do not try to use your database "like" a web server. Web servers have all sorts of clever "stuff" in them to protect themselves (and your Data) from the Ne'er-do-well's "out there" on the Wild, Wild Web. Your database does not. Regards, Phill W.
  3. At the point in your function where you're about to append some data into the file, test whether the file exists. If the file does not exist, then write the column headers into the file. Then, append the data into the file, regardless of whether you just wrote the headers or not. In the second and subsequent calls (recursive or not), the file will exist and so the headers will not be repeated. Regards, Phill W.
  4. There is no "Magic" here and, in the World of Programming, very little happens "automatically". Your code reads every row in the file, [poorly] constructs a SQL insert statement using the values in that row, and then executes that insert statement, thereby adding the row into the database. You need to change your code and add tests into it that will reject any row that contains data items that do not conform to your Business Rules (e.g. "Order Id cannot be zero"). How you report these failures back to the User is for you to decide. Regards, Phill W.
  5. It's called Data Validation. Just because the data comes from a file doesn't mean that your application should blindly "trust" it. The data is still coming from an untrustworthy source (i.e. anything that doesn't run on your own servers). Read each line from the file, validate the data, store only what "fits" and reject what doesn't (or rollback your Transaction to throw the whole lot away at the end of a "failed" upload run; YMMV). You are wide open to SQL Injection attacks. Read up about Parameterised Queries. Obligatory XKCD Reference - Little Bobby Tables. Regards, Phill W.
  6. Depends on how many "levels" you need to work with. If you only need, say, immediately related parent or child records, or even as far as grandparent or grandchild, you can do that with a regular query, just joining the table to itself the required number of times. select ... from table1 parent inner join tabel1 child on parent.child = child.parent inner join table1 grandchild on child.child = grandchild.parent ; But, as soon as you start getting arbitrary depth of nesting, a CTE is the way to go. Also, bear in mind that you want some way of stopping this recursion. You have no guarantee that, eventually, someone won't manage to create a loop in your data! (record1 -> record2 -> record3 -> ... -> record1). You can do this in the query itself or, perhaps better, with something (i.e. a Trigger) in the database to detect and reject the creation of such loops. You might remember to write your query with this Gotcha! in mind, but there's no guarantee that the next Developer to work on this Application will do the same! Regards, Phill W.
  7. Over the lifetime of this (or any other) Application, you will spend far more time reading its code than you will writing any of it so go for whichever form expresses your intention most clearly. Personally, I'd go with the former or, perhaps, an even more concise one: if ( ! isset( $_SESSION['user'] ) ) exit ; if ( 'SiteOwner' !== $_SESSION['user'] ) exit ; I'm not sure of the context in which this runs - perhaps a redirect to another page might be more appropriate than the "exit"? YMMV. Regards, Phill W.
  8. Excellent! If anyone asks, you're now applying the Principle of Least Privilege, getting your application work with the minimum level of permissions - just what it needs and nothing more. Also, you are now qualified to laugh openly at anyone that runs their entire Application as root. 😉 Regards, Phill W.
  9. This is a fundamental difference between files and directories. On a file, the execute bit makes the file .. well .. executable. On a directory, the "execute" bit makes the directory "navigable", i.e. you can get "into" it. At present, you can see that the directory exists - you can 'r'ead it in a listing of the parent directory - but you cannot navigate into it. To do that, the directory must have its Execute bit set. More typical permissions on a directory would be 750: User:rwx Group:rx Other:(None) This link explains it better, albeit talking about NFS and UFS, but the principle applies to all types of file system. It works because you're using the Group-level permissions, which allow you to delete things. You should leave it owned by www-data: that account is the owner of this data and works with it all the time; you're just popping in and out now and again (and, if you were to move on to another job, deleting your account would not take down the whole system!) Regards, Phill W.
  10. In a Client-Server application, like this, you have to consider two, very separate Environments: The secure Environment, in which your code runs and your database lives. Here, you can Trust everything. Everything is stored in "proper" Data Types. Life is Good. 🙂 The unsecure Environment, which is everything outside the secure Environment. This includes the User's browser and even the TCP/IP channel between your server and that browser. Here, you can Trust nothing. All data is encoded into Character Representations of itself (Users cannot enter "numbers" or "dates" as a computer or a database would store them). The trick, then, is how to get Data back and forth, between the two? For data coming "in", you have to clean, verify and decode those data to make them safe to be "admitted" into your "Inner Sanctum", most importantly, your database. This is basic, defensive programming-type stuff, plus things like Prepared SQL statements to minimise database vulnerability. That's where filter_var can help (once you've figured out what sort of Wee Beastie the datum is - trying to do numeric range checks on the letter 'q' always causes "fun" in testing. For data going "out", you have to encode those data to make them safe for the browser receiving them. That's what things like htmlentities and htmlspecialchars come in, to defend against Cross-Site Scripting (XSS) Attacks and other things. You should also consider more general things, like date and number formatting, which different User communities may want presented differently. Here's a comprehensive StackExchange Accepted answer on the subject. Regards, Phill W.
  11. Here's an idea to try and get your head around ... You cannot click on anything in PHP. PHP is a server-side technology so you can only get it do anything by sending it an HTTP request, by loading a URL, submitting a Form or sending it an AJAX request. Clicking is a client-side thing, usually supported by Javascript code that runs in your browser (and often sends AJAX requests under the covers). Fire up the "Developer Tools" in your favourite browser and step through the Javascript code as it runs. Regards, Phill W.
  12. You don't need JSON data (unless you actually want to store JSON data). Use two database connections - one to the local database, another to the cloud one - then loop through the data from the local one and insert it into the cloud one: $insertDB -> prepare('insert into cloud_users values ( :id, :username )'); $readDB -> prepare('select id, username from users order by 1'); $readDB -> execute(); while ( $row = $readDB -> fetch() ) { $insertDB -> execute( [ 'id' => $row['id'], 'username' => $row['username'] ] ); } Regards, Phill W.
  13. I'm guessing that's because you told it to? while( $r = mysqli_fetch_row( $result ) ) { echo "<option data-location_name='$r[1]' data-location_phone='$r[2]' value='$r[0]' selected> $r[0] </option>"; // ^ ^ ^ ID!! // | | ID // | Phone // Name // } Trying putting the name ($r['location_id']) inside the option element, not the id or, rather, whatever happens to be the first column that your query retrieves ($r[0]). Regards, Phill W.
  14. Taking these statements in order: $rec = mysqli_query( $db, "SELECT FROM joborder WHERE id=$id" ); This tries to execute a SQL query and puts the result - hopefully a set of results - into $rec. The function can also return false if its execution fails - which it will because your SQL in invalid. (What were you hoping to get from the joborder table?). I'll gloss over your SQL Injection Attack vulnerability for now. $record = mysqli_fetch_array( $rec ); Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in line 8 So now PHP is complaining that you're passing a Boolean value (false) as the first parameter to this function. Fix your SQL and try again. 🙂 Regards, Phill W.
  15. You have an array containing the field names that were passed into the function. That array is used to build the SQL statement so those columns will be returned in each row. Now, for each row in the returned data, you need to loop through your fields array and pull out each value from the row, by field name, something like this: while( $row = $results->fetch_assoc() ){ $dlm = ''; foreach( $fields as $field ){ echo $dlm . $row[ $field ]; $dlm = "\t"; } } Regards, Phill W.
  • 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.