Jump to content

Leaderboard

  1. requinix

    requinix

    Administrators


    • Points

      23

    • Content Count

      12,226


  2. Barand

    Barand

    Moderators


    • Points

      22

    • Content Count

      20,791


  3. kicken

    kicken

    Gurus


    • Points

      15

    • Content Count

      3,739


  4. gizmola

    gizmola

    Administrators


    • Points

      14

    • Content Count

      5,128



Popular Content

Showing content with the highest reputation since 04/25/2020 in Posts

  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
  6. 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. 🏳️
  7. 1 point
    The logic $number != 101 OR $number != 102 is always true. Look at the conditions separately for various cases: Case 1) $number = 99 $number != 101 => true $number != 102 => true true || true => true Case 2) $number = 101 $number != 101 => false $number != 102 => true false || true => true Case 3) $number = 102 $number != 101 => true $number != 102 => false true || false => true What you want is AND, not OR. Case 1) $number = 99 $number != 101 => true $number != 102 => true true && true => true Case 2) $number = 101 $number != 101 => false $number != 102 => true false && true => false Case 3) $number = 102 $number != 101 => true $number != 102 => false true && false => false
  8. 1 point
    Think about your logic. If $number is 101 then it <>102, right? And if $number is 102 then it <>101, right? Also, please do what the rest of the PHP community does: use the && || != operators instead of AND OR <>. The first group is what you see in programming languages. The second group is what you see in SQL. PHP is not SQL.
  9. 1 point
    Plan C - Embed the png image in the svg image and overlay with the name <?php $name = 'لقمان ابراهيم عباس عجلان'; $im = "<svg width='500' height='500'> <image x='0' y='0' width='500' height='500' xlink:href='images/snowman.png' /> <text x='250' y='110' text-anchor='middle' style='font-family:calibri; font-size:30pt; fill:#FFF;'>$name</text> </svg> "; echo $im; ?>
  10. 1 point
    The foreign key constraint needs a suitable index on the column, but it doesn't need to be an index dedicated to that column. So yes, you can double up your unique index if you create it properly. In order to re-use it, the foreign key column must be the first column in the index, so when you create it you want to do CONSTRAINT UQ_blah UNIQUE (product_type_code, id) and not CONSTRAINT UQ_blah UNIQUE (id, product_type_code). As mentioned though, in the scenario you laid out, the unique constraint is entirely unnecessary as your ID column is already unique by virtue of being the primary key so you'd just make a simple index on the product_type_code column. In a scenario where Id wasn't a primary key and a unique constraint was necessary then you could double-dip like that.
  11. 1 point
    Here is the javascript code corrected: function myFunction(imgs) { var expandImg = document.getElementById("expandedImg"); var imgText = document.getElementById("imgtext"); expandImg.src = imgs.src; imgText.innerHTML = imgs.alt; expandImg.parentElement.style.display = "block"; } function initMainImg() { var imgs = document.getElementsByClassName('column_images')[0].children[0]; myFunction(imgs); } initMainImg(); Here's a Codepen where I extracted this into a working example. With Codepen the javascript, css and html have to be separated into their sections, so this is just to show you that this code works with your styles and original markup, and the broken things removed. Basically what this code does is find the first div with class 'column_images' and gets the first child element, which is the image from that first div. It then passes that to myFunction so that an initial image will be loaded. To add a little variation to this, it's easy enough to pick one of the images at random to be initialized: function myFunction(imgs) { var expandImg = document.getElementById("expandedImg"); var imgText = document.getElementById("imgtext"); expandImg.src = imgs.src; imgText.innerHTML = imgs.alt; expandImg.parentElement.style.display = "block"; } function initMainImg() { var imgs = document.getElementsByClassName('column_images'); index = Math.floor(Math.random() * imgs.length); myFunction(imgs[index].children[0]); } initMainImg(); Here's the codepen for that version.
  12. 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.
  13. 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.
  14. 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.
  15. 1 point
    Your plan is fine. Just to throw this out in general, but over 50% of web traffic is now done with a mobile device. I would urge you do some research into responsive design. These days, you want to start with your mobile design and build it up for larger viewports, vs the old days when you started with your primary design and figured out how to scale it down. It's concentrated into css, with the exception of the newer picture element supported by most browsers. Layout is also important. Let's say that you have a layout where you have a picture and next to it a column of text talking about the image. On a mobile device you are going to move that all to 1 column, and will need the descriptive text to go underneath the image. You want to learn grid or flexbox (grid is the current state of the art). Images on mobile is a complicated subject, due to technology like retina. You can't just generate a scaled down version for mobile devices and serve that on a retina device, unless you don't care that the image may become illegible. Any illustrations would be best off rendered in svg, and in fact everything you can render in svg is ideal, because it intrinsically will scale up and down whereas any raster format images won't. Again for the raster images, this is where the html picture element is helpful. I hope that you are not using the web publishing model because you had concerns about "piracy" or content sharing. Having your content in a subscription website won't prevent privacy. Every browser has built in capability to save html, print, and print to pdf.
  16. 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.
  17. 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.
  18. 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.
  19. 1 point
    Not necessarily. Tons of websites out there are heavy on images, and many of them need those images to be available soon. You don't - we're talking about a textual book with some illustrations, not a picture book. (Even if it was a picture book, people only read one page at a time.) Meanwhile text isn't particularly strenuous on browsers. 40 pages * 500 words/page * 10 characters/word (spaces, punctuation, some HTML markup) = 200,000 characters. A fraction of a megabyte. So don't worry about it. Not yet. 40 pages could be a lot for a mobile device, so for that it would be worth considering paginating the content. Perhaps on desktop too, if you want the aesthetic of it. Unless pages are important concepts you need to account for, and you should try to avoid that if you can (pages are just so arbitrary), then you don't need to break it down beyond chapters. Worry about AMP later.
  20. 1 point
    Exceptions are different than errors, and there's a separate function to install a handler for them: set_exception_handler. That kind of handling is only for doing something like logging the error or whatever however, you can't use it to ignore the exception and continue. If you want your script to continue executing despite the exception, then you need to catch it with a try/catch block and handle it appropriately there.
  21. 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.
  22. 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.
  23. 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.
  24. 1 point
    You have absolutely no code that does anything with your query string. Start with this tutorial and then give it another try. https://phpdelusions.net/pdo
  25. 1 point
    Yes. You can certainly tell people about the subscriptions, anywhere you want, but unless you're prepared to make changes to your store and product models, it's easier to keep it all separate. Yes. It isn't impossible to add subscriptions to the store, but are you sure people will be looking at your online store for a subscription? If you advertise the store as a place to buy goods then they might not think it's the same place to buy access to the website. If it features prominently as a purchase place, maybe they would. You could also not offer the subscription as a "product" but as something they opt into. You can keep the details of the subscription as a sort of hidden product that they cannot add to their cart - only your PHP code can do it, which it would when the user goes through your subscription page thing. Treating the subscription as a product means you have to add a concept of conflicting products to your store. That might be useful for other things, I don't know, but if not then you're creating a lot more complexity for only one thing.
  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
    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.
  29. 1 point
    That is setting the value to 3, not testing if it is equal to 3. The equality operator is "=="
  30. 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 ") ?>
  31. 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)); }
  32. 1 point
    Show us the table structure/s you are working with and the csv layout. Tell us precisely what the goal is and let's see if we can come up with a more efficient way than 40,000 queries.
  33. 1 point
  34. 1 point
    The problem is that you are trying to print_r the result. The object created by that library is large and recursive so you can't just easily dump it.
  35. 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.
  36. 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.
  37. 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.
  38. 1 point
    I'm guessing when you changed to POST you did not change the array to $_POST which is why it didn't work.
  39. 1 point
    Either change the AJAX method or the PHP method. They have to match.
  40. 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
  41. 1 point
  42. 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.
  43. 1 point
    Turn error reporting on! Begin your php code with ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); Catch errors in PDO with 'try' and 'catch' (google this) example: try { $db = new PDO blah blah blah your stuff goes here } catch(Exception $e) { echo 'Exception -> '; var_dump($e->getMessage()); } I don't know anything about PDF... so I'm not reading your pdf code :-)
  44. 1 point
    Given your comments, I understand your concern. If you get to the point where your community is successful enough to have the issues you describe then you can pay people (or in some cases entice them to moderate for free) your community. This is how this forum works. The forum software does have tools that will blacklist emails and ip's, but neither of those are fool proof. They still make it an annoyance for anyone who has not automated signups. The average crackpot will simply move on. The other thing that we face like most sites with any significant user base, is attempts to spam or advertise. Again our small volunteer moderation group, along with the forum's ability for people to report posts they think violate our rules insures that we have almost no spam or abuse presence on the forum lasting for any significant amount of time. More often than not, if I see a report, it has already been handled by one of the other volunteers. Again, having too many users with some that won't follow the rules is a good problem to have. I simply happen to believe strongly that it's more important to concentrate on your MVP, and building your traffic and user base than it is to try and engineer a solution to a problem you don't yet have, when you haven't implemented the tried and true, if imperfect, controls that other sites utilize first.
  45. 1 point
    try <?php require 'db_inc.php'; $db = pdoConnect('test'); $res = $db->query("SELECT oracleid , name , des , clockingindate as clockin , clockingoutdate as clockout , timediff(clockingoutdate, clockingindate) as duration , total FROM attendance_record JOIN ( SELECT oracleid , sec_to_time(sum(timestampdiff(SECOND, clockingindate, clockingoutdate))) as total FROM attendance_record GROUP BY oracleid ) tots USING (oracleid) ORDER BY oracleid, clockingindate "); ?> <html> <body> <table border='1' style='border-collapse:collapse; width: 700px;'> <tr><th>OracleID</th><th>Name</th><th>Designation</th><th>Clock In</th><th>Clock Out</th><th>Duration</th></tr> <?php $previd = 0; foreach ($res as $row) { if ($row['oracleid'] != $previd) { // id changed so output total if ($previd != 0) { echo "<tr><td colspan='4'</td><td>Total:</td><td>$total</td></tr>"; } $previd = $row['oracleid']; } echo "<tr><td>{$row['oracleid']}</td> <td>{$row['name']}</td> <td>{$row['des']}</td> <td>{$row['clockin']}</td> <td>{$row['clockout']}</td> <td>{$row['duration']}</td> </tr> "; $total = $row['total']; } echo "<tr><td colspan='4'</td><td>Total:</td><td>$total</td></tr>"; // dont forget total for last id ?> </table> </body> </html>
  46. 1 point
    $date = 'Sun, Feb 9<br />3:00 PM ET'; $date = str_replace('<br />', ' ', $date); $dtobj = DateTime::createFromFormat('D, M j g:i A *', $date); echo $dtobj->format('Y-m-d H:i:s'); // 2020-02-09 15:00:00
  47. 1 point
    Hopefully you being new means you didn't write that code. Right? Because it's... not good. How about some information about this thing? What it's used for? Where? I ask because the problem it's trying to solve is much, much better addressed in other ways - other industry-standard, best practice sort of ways - and I want to know whether it'll be a bother to change it.
  48. 1 point
    I totally agree with @requinix regarding the two tables. However, if you are willing to compromise over the output, you could do something like this SELECT uid , name , SUM(CASE payment_type WHEN 'cash' THEN payment ELSE 0 END) as cash , SUM(CASE payment_type WHEN 'card' THEN payment ELSE 0 END) as card , cost , cost-SUM(payment) as balance FROM payment GROUP BY uid +------+------+------+------+------+---------+ | uid | name | cash | card | cost | balance | +------+------+------+------+------+---------+ | 1 | kim | 0 | 100 | 100 | 0 | | 2 | lee | 95 | 0 | 95 | 0 | | 3 | kent | 50 | 50 | 100 | 0 | | 4 | iya | 40 | 20 | 80 | 20 | +------+------+------+------+------+---------+ If you really need every transaction listed, the SQL becomes quite complex involving user variables and subqueries. It would be much easier to do in the PHP as you output each row. [EDIT] ... For the sake of completeness SELECT uid , name , cash , card , cost , cost-total as balance FROM ( SELECT name , CASE payment_type WHEN 'cash' THEN payment ELSE 0 END as cash , CASE payment_type WHEN 'card' THEN payment ELSE 0 END as card , 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 ) sorted JOIN (SELECT @previd:=0, @tot:=0) initialize ) recs; +------+------+------+------+------+---------+ | uid | name | cash | card | cost | balance | +------+------+------+------+------+---------+ | 1 | kim | 0 | 100 | 100 | 0 | | 2 | lee | 95 | 0 | 95 | 0 | | 3 | kent | 50 | 0 | 100 | 50 | | 3 | kent | 0 | 50 | 100 | 0 | | 4 | iya | 40 | 0 | 80 | 40 | | 4 | iya | 0 | 20 | 80 | 20 | +------+------+------+------+------+---------+
  49. 1 point
    Man I hope you live another 70 plus years thats incredible! I am honored to be talking to you right now... I hope we work again in the future and thank you again for all the time / help / and support! just wow!! god bless and may you continue to live healthy!
  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.