Jump to content

Leaderboard

  1. requinix

    requinix

    Administrators


    • Points

      24

    • Content Count

      12,226


  2. Barand

    Barand

    Moderators


    • Points

      23

    • Content Count

      20,792


  3. kicken

    kicken

    Gurus


    • Points

      16

    • Content Count

      3,739


  4. gizmola

    gizmola

    Administrators


    • Points

      14

    • Content Count

      5,128



Popular Content

Showing content with the highest reputation since 04/27/2020 in all areas

  1. 3 points
    People still use StackOverflow? That's only half a joke. Their community has always been toxic to newcomers and there's so much emphasis on correctness that anything less than perfect is unacceptable. And there's the hostility towards any form of discussion about what is right that I always mention when this subject comes up. SO is good when you're looking for a precise answer to a specific question, but it's terrible for actually asking the questions, or trying to weigh in as a new person with different answers. But I am glad they dethroned Expert Sex Change in search results. edit: If Your Common Sense/shrapnelcol came across this thread and decided they wanted to join our forum...
  2. 2 points
    $q = 'SELECT ID FROM table'; That is a SQL query. You have to run that query through your database, receive the results, and then look for each single matching image in the directory for every returned record. You can probably skip looking in the directory, though. It will only tell you if the file exists. So if you already know (or assume) the file exists then you don't need to bother looking.
  3. 2 points
    Don't worry about the IBD file. MySQL knows how to manage itself, you don't need to go second guessing it because of what you think you saw in Notepad. The question you think you're asking is whether to use an UPDATE or a DELETE+INSERT, but the question you're actually asking is how you should manage uploaded files that can be replaced. The answer to that is... well, it depends. There are two basic options: 1. Forget the previously uploaded file. You don't care about it. Take the new file and stick it wherever you want, update the database, and delete the old file. Gotta delete. Because if you forget about the old file then there's not much of a point to keeping the file itself around too. 2. Keep track of the previous file. You'd probably want a table that holds all the information for past and future uploads, and that's where you track them. For using those files, instead of storing the file information in whatever place, you reference the file in your upload information table. New image, new information row, and you update whatever place was affected. This lets you keep a history of everything, which probably isn't important for stuff like user avatars but is frighteningly important for stuff like monetary transactions. "Okay, I've decided that I want to do <whichever option>. But what about my literal question? Should I update or delete and insert?" Time to learn about an important concept in computing that disappointingly few programmers ever end up learning: atomicity. That's the noun version of "atomic", which means (in this case) that whatever operation you need to do can't be interrupted or broken in half or appear to anyone else as being anything less than one single action. Atomicity is important for stuff like files and databases because you basically never want to look at a file or data in the middle of some important operation. Imagine your site is popular. Really popular. Facebook or Twitter popular. Constant traffic to your servers. Now imagine a user uploads a new image. When the code is ready, it needs to go off into the database to make whatever changes it needs to make so the user has the new image. Say you go with DELETE and INSERT. Your code runs one query that DELETEs whatever, then another query that INSERTs. Sounds fine. Except remember how your site is always busy? It's quite possible someone was looking at your site at the moment in between those two queries. Since the DELETE has happened but not yet the INSERT, your code isn't going to find whatever data it needed to find and the user is going to get a bad experience. If that user was a CEO for a huge company that wanted to buy you out for lots of money, they might not do that now. A DELETE and INSERT is not atomic because there was that point in between the two queries. It was not "one single action". Instead you go with UPDATE. The database does whatever it does, but the clever people who wrote the software for it already knew about stuff like atomicity. And they made their system guarantee that UPDATEs are atomic. One single action. If you do an UPDATE when that rich CEO looks at your site, the database has guaranteed to you that either (a) the CEO will see the old data because the update hasn't happened yet, or (b) they'll see the new data because the update has happened. There is no moment in between old and new for stuff to be broken.
  4. 2 points
    Unlikely Quotes need removing... $query = "UPDATE `greencard` SET `comments`= '$comments', 'sent' = '$sent' WHERE `hospitalnumber`= '$hospitalnumber' and `PIN`= '$PIN'"; ^ ^ and it's easier just to use ... sent = NOW() WHERE ...
  5. 1 point
    $res = $db->query("SELECT name , timestampdiff(MONTH, doj, curdate()) as sen , timestampdiff(YEAR, dob, curdate()) as age FROM MEMBER ORDER BY sen DESC, age DESC "); $members = $res->fetchAll(); $titles = ['Leader', 'Assistant', 'Member 1', 'Member 2', 'Member 3', 'Member 4', 'Member 5', 'Member 6', 'Member 7', 'Member 8']; I originally set out on the round-robin route to allocate the members to teams ... $teams = []; $t = 0; foreach ($members as $r) { $teams[$t%6][] = $r; $t++; } ... but the problem with this method is it's bias. Team 1 gets the most experienced Leader and Team 6 gets the least experienced. On the next cycle, Team 1 gets the most experienced Assistant and Team 6 again gets the least, and so on for all levels. Therefore I'd recommend an approach which gets the players for each level then shakes the bags before allocating to teams $ranks = array_chunk($members, 6); // get a chunk of 6 members for each rank $tdata = ''; foreach ($ranks as $r => $rmembers) { shuffle($rmembers); // shake the bag - random allocation to teams $tdata .= "<tr><td class='rank'>{$titles[$r]}</td>"; foreach ($rmembers as $m) { $tdata .= "<td>{$m['name']} <span class='years'>({$m['sen']}/{$m['age']})</span></td>"; } $tdata .= "</tr>\n"; }
  6. 1 point
    FFS dil_bert. This is one of the most requested mod_rewrite things in existence. Do you know what I'm going to say next? I honestly don't know if you do. Google it.
  7. 1 point
    Easier to use file(). <?php $data = file('paulq.txt', FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES); $start = "sales_probability_dom"; $results = []; $pos = array_search($start, $data); // find start key while ($data[++$pos][0]=="\t") { // check for tab at start of line $results[] = trim($data[$pos]); } echo '<pre>', print_r($results, 1), '</pre>'; ?> giving Array ( [0] => @clear [1] => \"\": \"\" [2] => Closed Won: \"100\" [3] => Id. Decision Makers: \"40\" [4] => Needs Analysis: \"25\" [5] => Negotiation\/Review: \"80\" [6] => Perception Analasis: \"50\" [7] => Proposal\/Price Quote: \"65\" [8] => Prospecting: \"10\" [9] => Qualification: \"20\" [10] => Value Prospecting: \"30\" )
  8. 1 point
  9. 1 point
    This is a self fulfilling prophecy of failure. First off, you don't need to be an OOP expert to use classes and objects. With all the time you've spent here explaining to everyone why you can't or won't take their advice, you could have already watched the video, and learned a few things about modern PHP. Consider this my white flag. I give up. 🏳️
  10. 1 point
    This is not a teacher - student situation. As it happens, I have a good friend who is a college professor, as is his wife, and we talk about his classes and students fairly regularly. I know from his point of view, having standards that students have to meet is very much part of the job. There are assignments and tests. None of this is part of our discourse. In general, one of the most important elements of a community like this is the exposure to new ideas, technologies and methodologies, as well as exposure to a consensus on a baseline of competency. Your replies frequently seem to me to have elements of both FUD and NIH. I'm guessing you are familiar with both acronyms. I understand that you are concerned about what you don't know, and are unsure in regards to your ability to learn things that are new to you in the short and long term, but these topics did not come up by happenstance. You posted questions soliciting feedback, which is what you've received. In all the replies and feedback, I don't know if there's an instance where someone gave you an answer or opinion you've agreed with, that wasn't yours to begin with. It feels to me like an echo chamber, where you only want people to tell you that you were right from the get go. You seem to want to reduce this to a matter of opinion amongst equals, when that just isn't the case. I've done system architecture and engineering for my entire career. I know what's important, and I've tried to help you understand what that is, in dribs and drabs. I could at this point make a nice list of all the things you've disregarded, along with various excuses for why you know better than me what you need right now. At the end of the day, if we listed the requirements for what you want, what you've already built and how they can be integrated, sans a serious discussion of whether your requirements are sane or logical, or even prioritized correctly, there's a best practices way to build something new, and there's a way to make spaghetti, that will likely be a costly bug ridden failure. What the experienced practitioners here all know, is that doing it the right way isn't more difficult, nor does it take longer. Quite the contrary in fact. Doing it the right way produces a better product in less time because it's based on the assembly of pre-built and tested pieces, that more often than not have documentation and support. Again, I do this to try and help others, as do the other respondents who frequent this site. Some percentage of people find what they are looking for and some percentage do not. Most of us have been participating in this forum for many years. We've seen every type of question and questioner there is at this point. You might want to consider that when you question the relevance or urgency of the advice you've received.
  11. 1 point
    The order you want depends mostly on how you'll be using the index in your queries. I'd venture that in an order system you're most likely going to be joining orders to the details then to the products to generate invoices and such, which would have queries like: select * from orders o inner join order_details od on od.order_id=o.id inner join products p on p.id=od.product_id A query such as that would want your UK defined as (order_id,product_id). With that order the UK can be used to enforce your foreign key relationship on the order_id column and be used to speed up the join between the orders and order_details tables. If on the other hand you were doing a query based on products, such as to find popular products you might do queries like: select * from products p inner join order_details od on od.product_id=p.id For that kind of query you might consider the (product_id,order_id) order so you could use the UK to handle your product_id foreign key and the join to the products table. In either case, assuming both order_id and product_id are foreign keys then your UK can satisfy the index requirement for one of them and the other would need it's own index. Neither order is particularly bad or good in this situation as you need at least two indexes anyway. In such a table design you don't necessarily even need your ID column so you could just make your PRIMARY KEY be (order_id, product_id). Some people prefer always having a auto_increment primary key but in the scenario proposed it's not necessary and could be removed. More indexes mean more index management and disk space usage. That can potentially lead to slower performance when inserting/updating/deleting data, but wouldn't have any significant impact on selects. As such, you should try and limit your indexes to only those that you absolutely need to make your system function well. Until your system grows to a very large scale (millions of rows), it's unlikely you'd notice any problems from extra indexes though. There's no efficiency to be gained from having the separate PK and UK there as far as I am aware. A single multi-column primary key would be just as effective and save an index.
  12. 1 point
    These look a lot like registration keys for commercial software. The problem with registration schemes for many commercial products is that the scheme gets reverse engineered and then people are able to generate their own "legitimate" keys that register and unlock software. I was just pointing out that these might look like a registration key, but they aren't.
  13. 1 point
    Yes, make your screen shots however you want them at highest quality. With most quality mobile phones these days, as well as computers with high density displays like the macbook retina displays, you want your images to be 2x the desired size. So if you are going to display an image at 300px wide, then you want the image to be 600px. Here is an article that provides a visual demonstration of the noticeable difference in quality. On an Iphone or Samsung Galaxy, this could make the difference between a screenshot that is blurry and illegible and one that is clear. Having done some mass conversions in the past, Photoshop has tools for automating conversions, using Automate|Batch You should spend more time in the chrome developer tools if you believe this to be true.
  14. 1 point
    I don't care. If they can't remember their passwords then it's their fault. It's not your job to give them easy to remember passwords. Anything that suggests using MD5 for passwords is bad and you should never, ever look at again. Aren't you going to tell the students their passwords? I don't care how "sensitive" you think this is. A password is a password and there is no excuse for doing it wrong.
  15. 1 point
    As these are not registration keys AND they still have to be validated, you can simply generate a string of random numbers and characters, perhaps with some dashes between them. Here is a simple routine that will spit out strings in the format of xxxx-xxxx-xxxx, with 256^6 combinations (281 trillion+) combinations. function generateRandomCode() { return substr(chunk_split(bin2hex(random_bytes(6)), 4, '-'), 0, -1); } Very low chance you will generate duplicate codes, but you still want your DB to have a unique index on gift_code, and recover should you try and insert a duplicate. Anything like this would work, as again these are not registration codes, are unique, and would be linked to a particular user.
  16. 1 point
    mod_rewrite will allow you to take a "pretty url" and parse it into the the parameters your site understands. It doesn't automagically translate a url with parameters into a "pretty" url. You need to do that yourself. Hopefully you understand this. You have to understand regular expressions and capturing groups.
  17. 1 point
    I think you mean "pretty URL" or sometimes "friendly URL". Yes, you can do that with your .htaccess file, but it'll probably take some php coding as well. If you look at open-source CMSes and frameworks you'll get the basic idea - WordPress, Laravel, and Codeigniter are all examples I've personally used. Check out the .htaccess and index.php files, and follow the trail from there. You can also just google it and come up with plenty of examples.
  18. 1 point
    Don't be afraid of having to re-factor things in the future. You don't have to get the perfect layout from the get go. I find that many times even when I tried to plan for the future and design accordingly I'd usually miss something and end up doing some refactoring anyway. Best to just wait until you know what you need rather than guess at what you think you'll need. The book/component table structure sounds fine. If in the future you decide to split it up further you can. If in the future you decide to do pages/sections you could probably do so with relatively little changes to the tables.
  19. 1 point
    Aka, poor implementation. No JS is necessary to avoid loading the full sized version, you just link it separately. <a href="full-size.png"><img src="thumb.png"></a> I personally wouldn't, no. I have a dual-screen desktop so I'd open the book on one screen and Photoshop on the other. In the particular case of Photoshop it seems unlikely in general anyway to me. The person would need a desktop to run Photoshop on anyway so if they were trying to follow along and learn why not just open it in a browser on the desktop. Right, but if you're loading appropriately sized images then 30 images loading shouldn't really be a big deal. A full-size 1920x1080 scaled down to roughly phone-screen sized images should only be around 20-100k in size. 100k * 30 = ~3MB. 3MB on an average mobile connection would take all of 1 second to download. It's basically illegible sure, but that's where the previous point of having mobile-friendly versions comes in. Alternatively, link the illegible version to a full-sized version they can load and zoom/pan around on demand. A lot of people do things on mobile now, so it's certainly worth considering that market, but in my experience people still acknowledge when something isn't really a good fit for mobile and will move to a desktop/tablet in those scenarios (if possible). I have a friend that does practically everything from her phone mainly because for a long time she had nothing else. From time to time however she will come by to use my computer for things because they are just not mobile-friendly tasks and she recognizes that. Most people I know are still rational about what is and isn't a good fit for mobile, so I think your fear of everyone demanding a refund because your site isn't 100% mobile friendly is irrational. Sure, there may be some because people can be dicks but that's part of business. If your books deal with teaching software and that software is primarily a desktop thing I'd wager most people will interact with the site from a desktop. I'd make some considerations for mobile (responsive layout, smaller images) for those who might want to read some on their phone while away from a desktop (ie, commuting) but wouldn't spend a ton of time up front trying to make that experience perfect. I'd push that until later when everything else is up and running and more time is available to focus on that and/or real customers start requesting it.
  20. 1 point
    Hi gizmola, Thank you for taking time to reply. I appreciate your expertise with this subject. I'm a bit like a programming sheriff: trust noone and nothing / suspect everything. I don't even trust my own code. i use a counter in my foreach loops to be certain that they cannot become infinite loops via tampering: $count = 0; $maxentries = 100; ++$count; if ($count === $maxentries) { //i said 100 so why is this still going? exit now } i have designed my site to detect as many errors as possible. if file exists, if function exists, if isset everything. I don't want to help a hacker wreck my site. No stepping stones from me. I look at everything and question everything. In this case, i was startled by the history of background image names in the idb file like a fingerprint. Your explanation is most helpful to me. I am comfortable with this info. I've retained update as it is the best option. I can only do so much anyway. Atleast now i know more than i did yesterday. Best wishes to you and all members. I hope that you have a pleasant day. Stay safe and healthy and make the most of life, my friends.
  21. 1 point
    Take a closer look at the documentation for set_error_handler() and you'll notice it says you cannot handle fatal (E_ERROR) errors. The only thing you can do in that case is react to the fatal error after the fact: use register_shutdown_function() and error_get_last() to detect whether the script is ending because of a fatal error.
  22. 1 point
    With all due respect to you, you are an admitted novice. Many of the people who have replied to you have developed systems with php and mysql professionally for years if not decades. People are asking you to verify some things for a reason. When I'm diagnosing something, I may be running through a mental checklist that includes a vast number of variables you aren't aware of, having coded for a living. You think that it might not be saving the data (but you aren't sure) It could be saving the data, but just not reading it back You need error reporting turned on to see if there are hidden runtime errors or warnings that will pinpoint a problem Many people here will help you with your problem, but I will not for one reason only. I don't need you to change to PDO, although I agree it's a far nicer API to work with than mysqli. But I absolutely will not help anyone who is not using bound parameters and prepared statements. It's dangerous obsolete coding. Your code (including storing the passwords as md5 hashes without even a salt!!! harkens back to a time 10+ years in the past. Whether this is a hobby or not, there is no reason to write obsolete code when you can just as easily write modern code. It would take at most 10 minutes to read about the technique and add the code you would need to utilize that parameters. I can't be bothered to help someone debug something that is teaching them an improper practice any more than an electrician would teach someone how to work on wiring in their home, and not insist they turn off the circuit breaker and verify it was off with a multimeter. I'm not saying that you are the type of person who is stubborn and can't or won't try and learn, but in the past when people start to react the way you did as illustrated by your quoted comment, it's someone who is stubborn and easily offended. That does not lead to learning and a valuable expenditure of my time or the time of the other volunteers who answer questions.
  23. 1 point
    Okay. Fine. So don't track history. And now that you've made a decision I call tell you that I wouldn't store a history for this either. Stop caring about that file. I guess you missed the rather significant part of my post where I tried to explain what it is. Not sure what you're talking about but I'm 99% sure "loop while error is not present" is not the answer. sigh I'm done.
  24. 1 point
    you can examine the data in the database using a tool like phpmyadmin. next, you should have php's error_reporting set to E_ALL and display_errors set to ON, preferably in the php.ini on your system, so that php will help you by reporting and displaying all the errors that it detects. while you are making changes to the php.ini, set output_buffering to OFF, so that any messages from your code or non-fatal php error messages will be seen and not discarded at the header() redirects. you should also have error handling for all the statements that can fail. for database statements, just use exceptions for errors and in most cases let php catch and handle the exception, where it will use its error related settings to control what happens with the actual error information (database statement errors will 'automatically' get displayed/logged the same as php errors.) if you need, someone can post how to enable exceptions for errors for the mysqli database extension or if you switch to the much simpler PDO database extension.
  25. 1 point
    First never, ever put web page data directly into a database. Always use prepared statements. Second, you didn't post the code where you are executing the query. Third make sure error reporting is turned on: error_reporting(E_ALL);
  26. 1 point
    No, but I don't think you should include subscriptions in the store. A subscription is access to the site or whatever. The online store is for products. They are not the same thing.
  27. 1 point
    With PHP security, it's important to really learn what you are doing -- no guesswork! If you google "password_hash" you'll see a lot of explanations and examples. In the "olden days" passwords were encrypted, and stored in a database (which could later be hacked). Many encryption functions can result in strings that can be easily decrypted. In fact, there are a lot of websites that will attempt to decrypt your "super-duper encrypted string" for you, and usually do it in about 5 seconds. Nowadays, password "hashing" is popular. The password_hash function uses a random string each time to generate a "hash," which, when tested against the original password (using "password_verify"), will result in either a 'true' or a 'false.' You've noticed when you use "password_hash" you will get a different result each time. That is because this function uses a random string. In the case of your example, "PASSWORD_BCRYPT"). However, regardless how many password_hash results are generated against a specific password, they will all verify as "true." Nowadays, most websites choose to store actual password hashes in databases, rather than actual passwords. Instead of "PASSWORD_BCRYPT" it is popular to use "PASSWORD_DEFAULT" because as new algorithms are invented with PHP upgrades, "PASSWORD_DEFAULT" supposedly uses the latest and greatest. So, if it were me, even though "PASSWORD_BCRYPT" is considered pretty darn good, I would use "PASSWORD_DEFAULT" instead. Again, "security related PHP issues" is not the place to just throw in any line of code you found off the net as one might do when searching for "cool CSS button effects," etc. At the very minimum, do some googling and understand what you are doing. Google "password_hash" "password_verify" and learn all the caveats.
  28. 1 point
    Try it and find out. In the hour+ since you posted this thread, you could have installed MySQL Workbench, set it up, and started using it.
  29. 1 point
    I usually use it when dealing with mysql databases, but that's not very often. I'm not sure what you're expecting to do from it. It's fairly easy to setup and get connected to a DB so you can run queries and look through your tables and data. It has some design tools to help plan and diagram your database and the relationships between tables which take a little more effort to learn, but that's only if you want to use them. I haven't used phpMyAdmin in a long time so I'm not sure I could really compare the two, but I personally prefer having the separate desktop application like Workbench over a web app like phpMyAdmin. To use Workbench you need to be able to connect to the database server directly or via an SSH tunnel. On shared hosting that may or may not be possible, which is why many of them provide something like phpMyAdmin. For your own private server it shouldn't be a problem.
  30. 1 point
    I don't think you need bother with the json. Just define your table as something like this CREATE TABLE `bookmark` ( `bookmark_id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, `page_link` varchar(50) DEFAULT NULL, `css_icon` varchar(50) DEFAULT NULL, `icon_photo_link` varchar(50) DEFAULT NULL, `language` varchar(10) DEFAULT NULL, `icon_title` varchar(50) DEFAULT NULL, PRIMARY KEY (`bookmark_id`), UNIQUE KEY `unq_page_link` (`page_link`), KEY `idx_user` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  31. 1 point
    That isn't the most comprehensive requirements specification that I have worked from so there is a bit of guesswork involved, such as the comparison criteria being job number and line item matching, and which columns are to be updated from the csv data. If this is the case, your "production_data" table should have an index on these columns (as my temp table below has). Anyway, given those caveats, the processing would be along the lines below (4 queries instead of 40,000) and should give you a guide. <?php ## ## This initial section would normally be in an included file ## const HOST = 'localhost'; const USERNAME = '???'; const PASSWORD = '???'; const DATABASE = '???'; function pdoConnect($dbname=DATABASE) { $db = new PDO("mysql:host=".HOST.";dbname=$dbname;charset=utf8",USERNAME,PASSWORD); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $db->setAttribute(PDO::MYSQL_ATTR_LOCAL_INFILE, true); return $db; } ## ## Connect to DB server ## $db = pdoConnect(); ## ## create a temporary table to store the csv data ## $db->exec("CREATE TEMPORARY TABLE production_csv ( id int not null auto_increment primary key, enterprise tinytext, part_num text, description text, qty int, line_item varchar(11), job_num int, work_order varchar(50), psm varchar(50), date_change_flag tinyint, scheduled_ship_date date, on_hold tinyint, on_hold_reason varchar(50), total_hours decimal(10,2), worfc varchar(50), INDEX job_line (job_num, line_item) )"); ## ## load the csv data into the table ## $db->exec("LOAD DATA LOCAL INFILE 'prod_data.csv' INTO TABLE production_csv FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 LINES (@dummy, @dummy, enterprise, part_num, desc, qty, line_item, job_num, work_order, psm, date_change_flag, scheduled_ship_date, on_hold, on_hold_reason, total_hours, worfc) "); ## ## write matching production_data records to archive ## $db->exec("INSERT INTO production_archive SELECT pd.* FROM production_data pd JOIN production_csv USING (job_num, line_item) "); ## ## update the production_data table from the production_csv table ## $db->exec("UPDATE production_data d JOIN production_csv c USING (job_num, line_item) SET d.enterprise = c.enterprise, d.part_number = c.part_num, d.description = c.description, d.qty = c.qty, d.as400_ship_date = c.scheduled_ship_date, d.hold_status = c.on_hold ") ?>
  32. 1 point
    Ok foreach ( $dept_codes as $d ) { $production_history[$d] = []; } This can be replaced with array_fill_keys $production_history = array_fill_keys($dept_codes, []); Next up, foreach ( $dept_codes as $d ) { //loop through returned db rows foreach ( get_production_history( $order_id, $pdo ) as $row ) { if( $row['dept_code'] == $d ) { This ends up querying your database count($dept_codes) times when you only really need to do so once as far as I can tell. For each $dept_codes loop you're querying the database for all your results, then just filtering them out to only the ones matching the current department. Instead of doing that, just query your database once and process the results according to the department in the current row. foreach (get_production_history($order_id, $pdo) as $row){ $d = $row['dept_code']; //set start time if ( !in_array ( $row[ 'id' ], $production_history[ $d ]) && $row[ 'status_id' ] === 1 ) { $production_history[$d][ $row['id'] ] = array( 'submit_time' => $row[ 'submit_time' ], 'finish_time' => '', ); //record id $last_recorded = $row['id']; //set finished time } elseif ( $row[ 'status_id' ] === 3 ) { $production_history[$d][ $last_recorded ]['finish_time'] = $row[ 'submit_time' ]; } } Since your thread was prompted by anonymous functions, why not use them? //find records without a finish time and unset them foreach ( $production_history as $dept => $value ) foreach ($value as $k => $v) if (empty($v['finish_time'])) unset($production_history[$dept][$k]); //find departments without records and unset them foreach ( $production_history as $dept => $value ) if (empty($value)) unset($production_history[$dept]); Could be replaced with a mix of array_filter and array_walk: array_walk($production_history, function(&$entryList){ $entryList = array_filter($entryList, function($value){ return !empty($value['finish_time']); }); }); $production_history = array_filter($production_history); First array_walk loops over the $production_history array like your foreach loop, each value is passed to the function as $entryList (using a reference so we can modify it). Then the function uses array_filter to keep only entries which have a finish_time defined. //if on first entry for dept print parent if ( $dept_arr_count == 0 ) { //generate parent JSON entry $json[] = array( 'pID' => $dept, 'pName' => get_dept_name( $dept, $pdo ), 'pStart' => '', 'pEnd' => '', 'pClass' => 'ggroupblack', 'pLink' => '', 'pMile' => 0, 'pGroup' => 2, 'pParent' => 0, //need to set this for those that are children 'pOpen' => 1, 'pDepend' => '', 'pCaption' => '', 'pNotes' => '', ); } The if statement check here is unnecessary the way your data is setup. $production_history is a unique array of departments. As such, this part of the loop will only run once per department and there's no need to try and track if you're on a new department. $submit_time = (isset($production_history[$dept][$k]['submit_time'])) ? $production_history[$dept][$k]['submit_time'] : ''; $finish_time = (isset($production_history[$dept][$k]['finish_time'])) ? $production_history[$dept][$k]['finish_time'] : ''; $k is meaningless here. It's value is going to be whatever the last entry of the //find records without a finish time and unset them loop is (or undefined in my replacement version) You're not using these variables anywhere anyway so the entire lines could be removed. I'm not sure what you were attempting with these lines. $dept .''. $dept_arr_count+1 You might have an operator precedence issue here, it's unclear what your goal is. Concatenation and addition have the same precedence and are processed left to right so that expression is ($dept.$dept_arr_count)+1. You combine $dept and $dept_arr_count into a single number, then add one to it. Your spacing however, to me, suggests you intend to add one to $dept_arr_count first, then combine the two numbers. Achieving that requires a set of parenthesis. $dept . ($dept_arr_count+1) In either case, the empty string is unnecessary and can be removed. $production_history[$dept][$k]['submit_time'] $production_history[$dept][$k]['finish_time'] $production_history[$dept][$k] is the same as $v, so you can just use $v['submit_time'] and $v['finish_time'] instead. So, with all those suggestions applied, the new code would look something like this, assuming I didn't goof up somewhere: //fetch production history data if( isset ( $action ) && $action == 'get_production_history' ) { $order_id = $_GET['order_id']; $production_history = []; $last_recorded = 0; $dept_codes = [5,6,7,8,10,11,12]; $production_history = array_fill_keys($dept_codes, []); //loop through returned db rows foreach (get_production_history($order_id, $pdo) as $row){ $d = $row['dept_code']; //set start time if ( !in_array ( $row[ 'id' ], $production_history[ $d ]) && $row[ 'status_id' ] === 1 ) { $production_history[$d][ $row['id'] ] = array( 'submit_time' => $row[ 'submit_time' ], 'finish_time' => '', ); //record id $last_recorded = $row['id']; //set finished time } elseif ( $row[ 'status_id' ] === 3 ) { $production_history[$d][ $last_recorded ]['finish_time'] = $row[ 'submit_time' ]; } } array_walk($production_history, function(&$entryList){ $entryList = array_filter($entryList, function($value){ return !empty($value['finish_time']); }); }); $production_history = array_filter($production_history); $json = []; foreach ( $production_history as $dept => $value ) { //generate parent JSON entry $json[] = array( 'pID' => $dept, 'pName' => get_dept_name( $dept, $pdo ), 'pStart' => '', 'pEnd' => '', 'pClass' => 'ggroupblack', 'pLink' => '', 'pMile' => 0, 'pGroup' => 2, 'pParent' => 0, //need to set this for those that are children 'pOpen' => 1, 'pDepend' => '', 'pCaption' => '', 'pNotes' => '', ); //print children $dept_arr_count = 0; foreach ($value as $k => $v) { $json[] = array( 'pID' => $dept .''. $dept_arr_count+1, 'pName' => '', 'pStart' => $v['submit_time'], 'pEnd' => $v['finish_time'], 'pClass' => 'ggroupblack', 'pLink' => '', 'pMile' => 0, 'pGroup' => 0, 'pParent' => $dept, //need to set this for those that are children 'pOpen' => 1, 'pDepend' => '', 'pCaption' => '', 'pNotes' => '', ); $dept_arr_count++; } } header('Content-type: text/javascript'); print(json_encode($json, JSON_PRETTY_PRINT)); }
  33. 1 point
    Lately I've been getting real annoyed with SO and some of the stupidity that goes on there. As it happens, I stumbled upon the author of the PhpDelusions PDO and MySqli tutorials SO profile, and discovered that he/she had been banned from SO apparently due to too many complaints from the clueless he's tried tirelessly to educate. SO Profile here. Had 146k rep, over 4 years and Hundreds of answers on php, pdo and mysqli. I know many if not all of the admins, mods and gurus have linked people to phpdelusions in the past. The old adage "no good deed goes unpunished" seems applicable.
  34. 1 point
    Because those are the name/value pairs for the form. Every form is going to have something different there. The one in my image is from a XHR request that this site uses to check for new replies to a thread. Yes. That example doesn't need break points, it's a simple form where you'd just modify the DOM with the inspector tool like you mentioned above. Find the <input> tag you want to change and modify it's value attribute. The school's website used a JS library to scan a QR code using a webcam and took then made an XHR request with the data to perform the login. That type of situation is where you need to use break points and it's done via the Debugger tab in the XHR Breakpoints panel. Click the + to add one and enter some URL text to stop on. You probably saw it in the Cookies panel. Like everything else, there's nothing to stop someone from modifying that value to whatever they want. Like the product ID though, it doesn't matter much if they do. Most likely whatever they change it to would be invalid and just result in them starting a new session. If they did happen to change it to another valid session ID then they'd inherit that session. This is why session IDs need to be long, random and should not shared.
  35. 1 point
    Click on the request and it will open all the details in a side panel. One of the tabs of that panel is Params that shows the data that was submitted. There's lots of other info in the other panels that may be useful too. That depends a bit on how things are setup and what you want to do. Firefox has an Edit and Resend button you can use to craft a new request. This just sends the request and shows the response in the dev tools, it won't cause the page to change or trigger and result processing in javascript. If the form is a standard HTML form, just inspect it in the dom and modify the values then submit it. In the case of the schools site, the request was done via XHR so I set a break point on XHR requests (Debugger -> XHR Breakpoints) to find where the request originated from, then set another break point before the XHR request so I could modify the variables used to generate the request. No where in particular. It's just something you learn to do after being a web developer for years.
  36. 1 point
    If you go to the network tab of the dev tools and look at the requests it will show you exactly what was submitted by the form. Nothing on the client side of things is safe from tampering. I used all these tools/techniques a couple weeks ago to "hack" my way into my nieces school platform as their javascript QR code reader wasn't working and that's the only way she had to log in. I submitted a few bad login attempts with the dev tools open to see how they were submitting the data. After that I scanned her QR code with my phone to get the data then used the dev tools to change the data prior to submission so it was correct and get her logged in.
  37. 1 point
    Yes, every field has to have a name attribute for PHP to recognize it. So, yeah - it's a good point, depending on how you're pages are set up you'll probably want a hidden field to pass the product ID. My point was mostly don't pass the price for the product and assume that it hasn't been modified by the user. Which leads us to the next question: Sure - put this on your local dev environment: <?php if(!empty($_POST)){ print("<p>{$_POST['hidden_field']}</p>"); }else{ print("<p>not set</p>"); } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form method="post"> <input type="hidden" name="hidden_field" value="originally set!" /> <input type="submit" /> </form> </body> </html> Load the script into your browser and click the submit button; see where 'not set' changes to 'originally set!'? Groovy - now, open your developer tools from the browser and select the field with the 'hidden_field' name attribute and change the value attribute on that field to 'hacked, yo!'. Now click the submit button again. Without any sort of validation or server-side checking, the form happily passes 'hacked, yo!' to the processing script, and if that script processed a product price the user could easily change it to 0.00 or less. *edit* If they mess with the product ID.... well, honestly who cares? They'll just end up paying the correct price and getting a different product. It doesn't really help them out at all.
  38. 1 point
    Pass a product ID and quantity to the order form, then get the product price from the database and calculate the total price at that point. These fields should both be visible to the user. You can use a hidden honeypot or nonce field if you really want to, but if you're charging money I'm not sure many bots would actually pay for something at random (though I could be wrong so don't quote me on that). The only time you should deal with the price on the server-side (other than for output purposes) is when the order is being completed - you need to make sure the user doesn't use the developer tools to change the price during the sale, but once the sale is made you need to track how much the product cost at the time of the purchase in case the price changes in the future (which it will).
  39. 1 point
    Not to be a debbie downer, but the specific login script you mention uses MD5. If your website's password security is important, to you, please read "no one should be using MD5 anymore" at https://en.wikipedia.org/wiki/MD5 (MD5 is broken). From what I understand, php's built in "password_hash" function is much, much better than MD5. If you please read the question and answer about the "password_hash" function here. you might be inclined to go ahead and use mySQL. There are some pre-written login scripts on the net using "password_hash" that even I (a total PHP dumbo) can understand (just google "simple password_hash login scripts"). Just a thought.
  40. 1 point
    OK, that is what I figured. You are not accessing the table you think you are. Post the code connecting to the database.
  41. 1 point
    Make it so you can submit your form data to a script. Read your form data in the script using $_GET or $_POST depending on your form method. Create your query string from the form data. Concatenate the query string to your base URL. Issue your redirect to the new location.
  42. 1 point
    Either change the AJAX method or the PHP method. They have to match.
  43. 1 point
    No, it is not invalid. I didn't say it was invalid. I suggested that maybe there was a better way to do what you were trying to do. Because ^(?:^)([a-zA-Z+]){2,26}(\<wbr\>\&shy\;)?([a-zA-Z+]){2,12}?(?:$)$ 1. You have unnecessary (?:^) and (?:$) assertions 2. You put a + in the character set, where it will mean a literal plus and not repetition 3. The parentheses for grouping around the letters do nothing 4. < > & ; are not special characters and do not need to be escaped 5. The anchors and the fact that this looks for the hyphen in a string suggests you're running this regex multiple times to add multiple hyphens? Some of those are minor flaws and some of those impact how the regex works, but mostly it just didn't feel right to me and I'm not sure that it will properly handle all the various inputs you haven't tested yet.
  44. 1 point
    Then I'm not sure why you have this complicated scheme of checking the length of the whole string, and looking strictly at letters. Simple hyphenation is fairly simple: insert a hyphen into a word after about X characters but not within Y characters of its end. Sounds like you're going for X=10 and Y=2, so RequinixIsAregexPro hyphenates as RequinixIs-AregexPro, Ruechenseitentiere as Ruechensei-tentiere, and Ruckenseitentiere as Ruckenseit-entiere. You can adjust your X and Y to make these examples look better, but you can't set up hyphenation rules for every single word. Especially not with German. /\pL{10}(?=\pL{2})/u Find 10 letters, require that there are at least two more after it, and insert a soft hyphen. If you have to deal with HTML then sure it's a lot more complicated. You need to ignore <script>s and their contents, and ignore other tags but not their contents. Basically the only way you can do that is look letter by letter. Count out 10 letters, skipping over HTML as you go. /(\pL(?><(script).*?<\/\2>|<.*?>)*){10}(?=\pL{2})/su
  45. 1 point
    You don't have to do everything with a regular expression. If you want to limit the length of a string, there are easier ways. What you have there is... well, I take it you've spent a lot of time throwing syntax at it until you got something that worked? Do me a favor and state the full and exact requirements for your input string and we'll see if we can't come up with something that does it all in a cleaner way.
  46. 1 point
    There's the problem. Your distro manages PHP extensions with the INI files, where opcache is enabled, but there's also a modification to your php.ini to load it again. Open up php.ini and remove the zend_extension line. Then look nearby for other edits that also don't belong in that file.
  47. 1 point
    Your randomNr array contains 10 elements so foreach($randomNr as $number) will give 10 columns. You need to pick a random 6 numbers out of the 10. Separate the php code from the html. Use CSS for styling the output. Example <?php $randomNr = range(0,9); $bingokaart = display($randomNr); function display ($arr) { $result = ""; for ($row = 1; $row < 7; ++$row) { $rand6 = array_rand($arr, 6); $result .= '<tr>'; foreach ($rand6 as $n) { $result .= "<td>$row$arr[$n]</td>"; } $result .= "</tr>\n"; } return $result; } ?> <!DOCTYPE html> <html> <head> <title>Sample</title> <style type="text/css"> table { border-collapse: collapse; } td { padding: 2px; } </style> </head> <body> <table border='1'> <?= $bingokaart ?> </table> </body> </html>
  48. 1 point
    An alternative to the 2-table option is to treat costs as transactions, just like payments (cost amounts +ve, payment amounts -ve in this example)... DATA TABLE: payment +------+------+------------+--------------+---------+ | uid | name | trans_date | payment_type | payment | +------+------+------------+--------------+---------+ | 1 | kim | 2020-03-01 | cost | 100 | | 1 | kim | 2020-03-02 | card | -100 | | 2 | lee | 2020-03-01 | cost | 95 | | 2 | lee | 2020-03-02 | cash | -95 | | 3 | kent | 2020-03-01 | cost | 100 | | 3 | kent | 2020-03-03 | cash | -50 | | 3 | kent | 2020-03-04 | card | -50 | | 4 | iya | 2020-03-01 | cost | 80 | | 4 | iya | 2020-03-05 | cash | -40 | | 4 | iya | 2020-03-06 | card | -20 | +------+------+------------+--------------+---------+ then SELECT uid , name , date , cost , cash , card , total as balance FROM ( SELECT name , DATE_FORMAT(trans_date, '%b %D') as date , CASE payment_type WHEN 'cash' THEN -payment ELSE '-' END as cash , CASE payment_type WHEN 'card' THEN -payment ELSE '-' END as card , CASE payment_type WHEN 'cost' THEN payment ELSE '-' END as cost , @tot := CASE @previd WHEN uid THEN @tot+payment ELSE payment END as total , @previd := uid as uid FROM ( SELECT * FROM payment ORDER BY uid, trans_date ) sorted JOIN (SELECT @previd:=0, @tot:=0) initialize ) recs; +------+------+---------+------+------+------+---------+ | uid | name | date | cost | cash | card | balance | +------+------+---------+------+------+------+---------+ | 1 | kim | Mar 1st | 100 | - | - | 100 | | 1 | kim | Mar 2nd | - | - | 100 | 0 | | 2 | lee | Mar 1st | 95 | - | - | 95 | | 2 | lee | Mar 2nd | - | 95 | - | 0 | | 3 | kent | Mar 1st | 100 | - | - | 100 | | 3 | kent | Mar 3rd | - | 50 | - | 50 | | 3 | kent | Mar 4th | - | - | 50 | 0 | | 4 | iya | Mar 1st | 80 | - | - | 80 | | 4 | iya | Mar 5th | - | 40 | - | 40 | | 4 | iya | Mar 6th | - | - | 20 | 20 | +------+------+---------+------+------+------+---------+
  49. 1 point
    E.G. $res = $conn->query("SELECT i.model_id , i.model_name , c.category_id as cat_id , c.model_category_name as cat_name FROM model_index i JOIN models_category_ids USING (model_id) JOIN models_category c USING (category_id) "); $data = []; foreach ($res as $r) { if (!isset($data[$r['model_id']])) { $data[$r['model_id']] = [ 'name' => $r['model_name'], 'cats' => [] ]; } $data[$r['model_id']]['cats'][$r['cat_id']] = $r['cat_name']; } /* $data = Array ( [1] => Array ( [name] => John Doe [cats] => Array ( [1] => IT Devloper [3] => Mechanic ) ) [2] => Array ( [name] => Laura Norder [cats] => Array ( [2] => Photographer ) ) ) */
  50. 1 point
    ...bold? I'm confused. It sounds like you think I told you not to use regular expressions. Or that someone told you not to. That's wrong. They're fine to use as long as you're careful about how you write them. If you write anything complicated, test it with very large inputs that should match and some that should not match. You'll probably find out real quick whether there's a problem.
This leaderboard is set to New York/GMT-04:00
  • Newsletter

    Want to keep up to date with all our latest news and information?
    Sign Up
×
×
  • 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.