Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 03/04/2013 in all areas

  1. Something like this? CODE <?php include 'db_inc.php'; // YOUR CONNECTION $pdo = pdoConnect('movies'); // CODE GOES HERE ################################################################################ ## PROCESS AJAX REQUESTS ################################################################################ if (isset($_GET['ajax'])) { $res = $pdo->prepare("SELECT m.id as movie_id , m.title , m.image , g.description as genre , CONCAT(m.running_time DIV 60, ' hrs ', m.running_time % 60, ' mins') as running_time , date_format(sg.screen_on, '%W, %D %b') as date , s.name as screen_num , TIME_FORMAT(sg.screen_at, '%H:%i') as start_time FROM screening sg JOIN screen s ON sg.screen_id = s.id JOIN movie m ON sg.movie_id = m.id JOIN genre g ON g.id = m.genre WHERE dayname(screen_on) = :day ORDER BY movie_id, screen_on, sg.screen_at "); $res->execute([ 'day' => $_GET['day'] ]); $data = []; # # Put data into an array with same structure a required output # - array of movies, each movie having arrays of screenings # foreach ($res as $r) { if (!isset($data[$r['movie_id']])) { $data[$r['movie_id']] = [ 'title' => $r['title'], 'image' => $r['image'], 'genre' => $r['genre'], 'runtime' => $r['running_time'], 'screenings' => [] ]; } $data[$r['movie_id']]['screenings'][$r['date']][] = ['start' => $r['start_time'], 'sno' => $r['screen_num'] ]; } exit(json_encode($data)); } ?> <!DOCTYPE html> <html lang="en"> <head> <meta name="generator" content="PhpED 12.0 (Build 12010, 64bit)"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>olumide</title> <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css"> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script type='text/javascript'> function showScreenings(day) { $("#movie-listings").html("") $.get( "", {"ajax":1, "day":day}, function(resp) { $.each(resp, function(mid, mdata) { let title = `<h2>${mdata.title}</h2><h4 class='w3-text-gray'>${mdata.genre} (${mdata.runtime})</h4>` $("#movie-listings").append(title) $.each(mdata.screenings, function(dt, ddata) { let datesub = `<h3>${dt}</h3>` $("#movie-listings").append(datesub) $("#movie-listings").append("<div class='screenings'") $.each(ddata, function(k, sdata) { let scr = `<div class='screening'><b>${sdata.start}</b><br>${sdata.sno}</div>` $("#movie-listings").append(scr) }) $("#movie-listings").append("</div>") }) }) }, "JSON" ) } </script> <style type='text/css'> .days { padding: 16px; text-align: center; } .screening { width : 20%; display: inline-block; margin-right: 16px; margin-bottom: 8px; padding: 4px; border: 5px solid black; font-size: 9pt; } </style> </head> <body> <nav class="days"> <button onclick="showScreenings('Monday')">Monday</button> <button onclick="showScreenings('Tuesday')">Tuesday</button> <button onclick="showScreenings('Wednesday')">Wednesday</button> <button onclick="showScreenings('Thursday')">Thursday</button> <button onclick="showScreenings('Friday')">Friday</button> <button onclick="showScreenings('Saturday')">Saturday</button> <button onclick="showScreenings('Sunday')">Sunday</button> </nav> <div id='movie-listings'class='w3-content w3-padding w3-card-4'> <!-- LISTINGS GO HERE --> </div> </body> </html>
    3 points
  2. I guess you don't understand that phpfreaks is a free site, with expert help provided by volunteers. Given the fact that everyone is donating their time and expertise to try and help people like yourself, the argument that you host a free site with source code you got from somewhere else for free, means you shouldn't ever have to learn anything (which can be learned in a few hours) will not get you much sympathy here.
    3 points
  3. By far the best the best way is to fix whatever they are warning you about.
    3 points
  4. @HawkeNN I want to clarify some things for you. Most code that was written for PHP 7.x will still run fine under php 8. For the most part PHP 8 added new features. There are "Breaking Changes" that were made, listed here: https://www.php.net/manual/en/migration80.incompatible.php but it is unlikely that is the problem with your code from some of the errors I saw listed. For example, the "headers already sent" error is a common one and has been around since php 3 at least. It has to do with code that sends output to the browser (as in the case of a script that intermixes HTML and php) and then tries to set HTTP header values. At that point, the HTTP request has already been sent with whatever headers it had, and it's too late to add or modify them. PHP session use is one function that sets header values because it sets a cookie. Some of the advice that you got is related to common techniques for trying to solve the issue. Equally important is your hosting configuration for PHP. Changes to the configuration of PHP from a version upgrade, can turn on settings that might have been off previously, or warnings being emitted that weren't before. This can then trigger output which also causes the "headers already sent" message. I suspect that this is part of your problem here, and really requires some debugging of your hosting setup. This was already brought up to you, in that there will be a php.ini (and often other assorted xyz.ini files that are included by the main php.ini) where settings can be made or changed to re-configure php. In conclusion, this is a PHP developer forum. From looking at this thread, you aren't likely to have a good outcome here, because you aren't a php developer. My sincere advice is to just find yourself a developer (this forum is chock full of them) you can pay a fee to, in order to resolve your issues and get your site working again. We have established that the code is bad, and that there is likely a few different things going on that are somewhere between the configuration of your server to possible improvements to the code you have. In other words, this is a problem for an experienced developer that requires debugging. I probably shouldn't say this, but my knee jerk reaction is that getting your code to work is not that big of a job, but looking at a thread like this is frustrating to read, because in my experience it is not going anywhere. There isn't any long term value to it for our forum, and you are not going to become an active member of the forum, nor learn PHP development, so there is nothing in it for us, or the community at large.
    3 points
  5. With a couple of db tables like this Table: user Table: role +---------+----------+--------+ +---------+---------------+-----------+------------+ | user_id | username | points | | role_id | role_name | point_min | points_max | +---------+----------+--------+ +---------+---------------+-----------+------------+ | 1 | John | 66 | | 5 | - | 0 | 100 | | 2 | Paul | 101 | | 6 | Contributor | 101 | 1000 | | 3 | George | 3000 | | 7 | Author | 1001 | 10000 | | 4 | Ringo | 200000 | | 8 | Editor | 10001 | 100000 | +---------+----------+--------+ | 9 | Administrator | 100001 | 999999999 | +---------+---------------+-----------+------------+ Then a simple query SELECT username , rolename FROM user u JOIN role r ON u.points BETWEEN r.points_min AND r.points_max; does the job for you +----------+---------------+ | username | rolename | +----------+---------------+ | John | - | | Paul | Contributor | | George | Author | | Ringo | Administrator | +----------+---------------+
    3 points
  6. Use DATE type columns for your dates, not varchar. Have your leaving dates either a valid date or NULL. SELECT eemp_id , fname , lname , AVG(timestampdiff(MONTH, joining_date, coalesce(leaving_date, curdate()))) as av_mths FROM employee_details ed JOIN employee e ON e.empid = ed.eemp_id GROUP BY eemp_id HAVING av_mths >= 36;
    3 points
  7. If you are outputting an image from a DB blob field, then here's an example... // EMULATE DATA FROM THE DATABASE $type = 'image/png'; $comments = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.'; $image_data = file_get_contents('images/snowman.PNG'); // OUTPUT THE DATA echo "<div style='width:396;'> <img src='data:{$type};base64," . base64_encode( $image_data ) . "' width='394' height='393'> <p>$comments</p> "; RESULT
    3 points
  8. Don't use "SELECT * ". Specify the columns you want. This makes it easier for others, like me, to understand what is in the table and what the query is doing. Indent your code to show the nested structure of loops etc. If you had done those I might have given this problem more than a cursory glance. So you'll have to settle for a generic example of using a recursive function to give an indented list of parent/child elements. Also, Don't run queries inside loops. Use JOINs to get all the data in a single query THE DATA TABLE: category +----+---------+--------+ | id | name | parent | +----+---------+--------+ | 1 | happy | 0 | | 2 | comet | 0 | | 3 | grumpy | 0 | | 4 | prancer | 1 | | 5 | bashful | 1 | | 6 | dancer | 2 | | 7 | doc | 2 | | 8 | blitzen | 2 | | 9 | dasher | 3 | | 10 | donner | 1 | | 11 | vixen | 1 | | 12 | cupid | 8 | +----+---------+--------+ THE OUTPUT THE CODE <?php $sql = "SELECT id, name, parent FROM category"; $res = $db->query($sql); // // store arrays of items for each parent in an array // while (list($id, $name, $parent) = $res->fetch(PDO::FETCH_NUM)) { $data[$parent][] = array('id'=>$id, 'name'=>$name); } /** * recursive function to print a category then its child categories * * @param array $arr category data * @param int $parent parent category * @param int $level hierarchy level */ function displayHierarchy(&$arr, $parent, $level=0) { if (isset($arr[$parent])) { echo "<ul>\n"; foreach($arr[$parent] as $rec) { echo "<li class='li$level'>{$rec['name']}\n"; if (isset($arr[$rec['id']])) displayHierarchy($arr, $rec['id'], $level+1); echo "</li>\n"; } echo "</ul>\n"; } } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Example</title> <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script type="text/javascript"> </script> <style type="text/css"> body { font-family: verdana,sans-serif; font-size: 11pt; padding: 50px; } li { font-weight: 600;} .li0 { color: red; } .li1 { color: green; } .li2 { color: blue; } </style> </head> <body> <?php displayHierarchy($data, 0); ?> </body> </html>
    3 points
  9. Too many people are obsessed with "filtering" bad inputs. You don't have to "filter" anything. You don't have to remove HTML tags. You don't have to remove SQL keywords. You don't have to strip quotes or backslashes. All you have to do is make sure that whatever the user typed doesn't screw around with what you're trying to do. Want to put it into HTML? Make sure it doesn't screw around with your HTML. Want to put it into SQL? Make sure it doesn't screw around with your SQL. Want to send it in JSON? Make sure it doesn't screw around with your JSON. And every single one of those situations has a simple, single best-practice solution: HTML? Use htmlspecialchars with ENT_QUOTES* and the correct charset. SQL? Use prepared statements. JSON? Use json_encode. That's it. No filter_vars or filter_inputs, no strip_tags, no regular expressions, nothing stupid like that. User wants to look cool and type <script> tags into their forum post? Go ahead and let them, because it'll just show up as plain and simple text. Like it just did now. * Only actually required if you are putting the input into an single quote-delimited tag attribute. Using double quotes for your attributes? Not outputting into an HTML tag? Then you don't technically need ENT_QUOTES.
    3 points
  10. I enjoy the challenge when someone posts a problem I can get my teeth into.
    3 points
  11. 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...
    3 points
  12. A few notes about text bounding boxes which, I hope, will help in precise placement of your text. Suppose I have the text string "The lazy fox" which I want to display using 150pt Vivaldi . My image is 4896 x 3672 and I want the text placed at the bottom right but 250 pixels from the edges of the image. $box = imagettfbbox(150,0,'c:/windows/fonts/vivaldii.ttf','The lazy fox'); gives this array of coordinates of the four corners $box = Array ( [0] => 23 [1] => 55 [2] => 871 [3] => 55 [4] => 871 [5] => -140 [6] => 23 [7] => -140 ) You may wonder why it can't just give a rectangle from (0,0) to (width, height) to make sizing simple, but there is extra information to be extracted from the array Text width = (871 - 23) = 848 Text height = 55 - (-140) = 195 The baseline will be 140px from the top The text is offset 23 px to the right. My text, therefore, will be in a rectangle 848 x 195 positioned 250 px from right and bottom edges. The top left x coord of the rectangle will be (4896 - 250 - 848) = 3798 and top left y coord will be (3672 - 250 - 195) = 3227. However, to land the text precisely into this area we position it on the baseline and at the required x offset, ie (3798 - 23 , 3227 + 140) = (3775, 3367). I use a simple custom function to assist with this process function metrics($font, $fsize, $str) { $box = imagettfbbox($fsize, 0, $font, $str); $ht = abs($box[5] - $box[1]); $wd = abs($box[4] - $box[0]); $base = -$box[5]; $tx = -$box[0]; return [ 'width' => $wd, 'height' => $ht, 'ascent' => $base, 'offsetx' => $tx ]; } $box = metrics ('c:/windows/fonts/vivaldii.ttf', 150, 'The lazy fox'); $box = Array ( [width] => 848 [height] => 195 [ascent] => 140 [offsetx] => -23 )
    3 points
  13. Don't use $GLOBALS. Forget it exists. There is never a good reason to use it. Pretend you never saw it.
    3 points
  14. +----------------+ +----------------+ | Make sure to |---+ +------->| (e.g. Courier) | +----------------+ | | +----------------+ | | | | +----------+ | | +->| use a |---+ | | +----------------+ +----------+ | | +------->| and use spaces | | | +----------------+ | +----------------+ | | +--->| monospace font |-----+ | +----------------+ | +----------+ | | not tabs |<----------+ +----------+ | +--------------------------------------------------------------------------+ | V +---------------+ | It also helps | +---------------+ | | | +-------------------+ +-------------------+ +------------------------>| if you sometimes |---------------------->| switch between | +-------------------+ +-------------------+ | | +-----------------+-----------------+ | | | | +-------------------+ +-------------------+ | overtype | | insert | +-------------------+ +-------------------+ | | | | | +----------+ | +----------=>| modes |<----------+ +----------+
    3 points
  15. The code in each switch is identical so all it achieves is to ensure the calculation uses only the defined list of diameter options. Just use an array of the valid values to verify the values. You can use the same array to generate the option list <?php $diam_vals = [2,3,4,6,8,10,12,14,16,18,20,22,24,26]; $results = ''; if ($_SERVER['REQUEST_METHOD']=='POST') { $x = $_POST['x'] ?? 0; $y = $_POST['y'] ?? 0; $diametre = $_POST['diametre'] ?? 0; if ($x > 0 && $y > 0 && in_array($diametre, $diam_vals)) { $rayon = $diametre * 38.1; $dc = $x/2; $ad = ($y/2)-$rayon; $ac = sqrt(pow($ad,2) + pow($dc,2)); $ec = sqrt(pow($ac,2) - pow($rayon,2)); $LongueurBayonette = $ec*2; $alpha = asin($dc/$ac); $alpha = $alpha*180/M_PI; $beta = acos($rayon/$ac); $beta = $beta*180/M_PI; $angle = 180-$alpha-$beta; $results .= "X = " . $x . "mm" . "<br/>"; $results .= "Y = " . $y . "mm" . "<br/>"; $results .= "Longueur = " . number_format($LongueurBayonette,1) . " mm" . "<br/>"; $results .= "&beta; = " . number_format($angle,1) . "°" . "<br/>"; $results .= "Rayon = " . $rayon . " mm" . "<br/>"; $results .= "&phi; = " . $diametre . '"' . "<br/>"; } else { $results = 'Inputs are not valid'; } } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Simplified Example</title> </head> <body> <form method="post" action=""> <fieldset> X: <input type="text" name="x" value="" /> <br/> Y: <input type="text" name="y" value="" /> <br/> Diametre: <select name="diametre"> <option value="0"> </option> <?php foreach ($diam_vals as $d) { echo "<option value='$d'>$d</option>\n" ; } ?> </select> <input type="submit" value = "Calculer" /> </fieldset> </form> <br> <?=$results?> Just curious - do you have a diagram of how those values relate to one another. It metions "rayon" and "bayonnette" so my guess is that it is some kind of laser rifle with attached bayonet (but I could be wrong) ?
    3 points
  16. Once again we have no idea what the data you are processing looks like. Post the output from this code... echo '<pre>' . var_export($data, 1) . '</pre>';
    2 points
  17. 2 points
  18. password_hash() and password_verify()
    2 points
  19. The redirections are part of the setup for running a command. > and < tie the STDOUT and STDIN streams to a file. This processing is handled by the shell, not the program being executed, so they are not considered part of the programs argument list. Since this is pre-execution setup work as well, the redirection happens before the program is executed, thus happen even if the program execution fails. So, given the command line: zcho It is cold today! > winter.txt The shell would Parse the line into it's components Argument list: ['zcho', 'It', 'is', 'cold', 'today!'] Redirections: STDOUT -> winter.txt Setup STDIN, STDOUT, and STDERR STDIN: tied to the shell's current STDIN stream STDOUT: tied to a new stream created by opening winter.txt for writing (with truncation) STDERR: tied to the shell's current STDERR stream. Extract the first argument and use it as the program/command name (zcho) Attempt to execute the program/command with the arguments given You can confirm the redirection happens first by running your invalid command with STDERR redirection: kicken@web1:~$ zcho It is cold today! 2> error.txt kicken@web1:~$ cat error.txt -bash: zcho: command not found The error message from the zcho command is redirected to the error.txt file rather than displayed in the terminal.
    2 points
  20. don't bother with the mysqli extension. it is overly complicated, inconsistent, and in the case of procedural vs OOP statements, has different error responses for the same root problem. instead, use the much simpler, consistent, and more modern PDO extension. in php8+, both the mysqli and PDO extensions use exceptions for errors by default. the line of code that @Barand posted enables exceptions for errors for the msyqli extension. when you use exceptions for database statement errors, php will 'automatically' display or log the raw database errors, via an uncaught exception error. therefore, you can remove any existing error handling logic, since it won't ever get executed upon an error, simplifying the code. you should also name the connection variable as to the type of connection it contains, $mysqli/$pdo. this will let anyone looking at the code know what extension it is using, and also let you search for which code has been converted and which hasn't. you also need to use a prepared query when supplying external, unknown, dynamic values to a query when it gets executed, so that any sql special characters in a value cannot break the sql query syntax, which is how sql injection is accomplished. if you switch to the much simpler PDO extension, after you prepared the query, you can simply supply an array of the input values to the ->execute([...]) call.
    2 points
  21. You won't learn anything useful about SQL pursuing this design because the design is fundamentally flawed and directly opposed what SQL is designed to do. My answer is that you don't. I'm sure there is a way for it to be done, but doing so would teach you nothing useful. The correct solution to your problem is to re-design your table structure, then use SQL as it's intended to be used rather than fight against it trying to make a poor design work. This shows yet another potential reason why your design is flawed. Why do you have multiple rows for the same link? If the answer is "To have more than 4 key words" then that's wrong. The multi-table solution gives you the ability to have an unlimited number of keywords per link.
    2 points
  22. Alternatively, assuming they all have same rigid structure, ... $fp = file('weather.html', FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES); $data = []; foreach ($fp as $line) { switch (substr($line, 0, 4)) { case '<!--' : if ($line[4]!=' ') { $section = substr($line, 4, -8); } break; case '<td>' : list($name, $value) = getData($line); $data[$section][$name] = $value; break; default : continue 2; } } function getData($line) { $l = substr($line, 4, -5); return explode('</td><td>', $l); } // View the results echo '<pre>' . print_r($data, 1) . '</pre>'; giving ... $data = Array ( [MISCELLANEOUS] => Array ( [Name of Station] => AzureCove [City (from NOAA Setup)] => Garden City [State (from NOAA Setup)] => Utah [Elevation (from NOAA Setup)] => 5954 ft [Latitude (from NOAA Setup)] => 41° 56' 12" N [Longitude (from NOAA Setup)] => 111° 23' 20" W [Date on the PC] => 03/13/23 [Time on the PC] => 4:06a [UTC Time] => 10:06a [UTC Date] => 03/13/23 [Date on the Station] => 03/13/23 [Time on the Station] => 4:05a [Sunrise Time] => 7:41a [Sunset Time] => 7:30p [Current Weather Forecast *] => Partly cloudy with little temperature change. [Current Moon Phase] => Last Quarter [EMC] => --- [EMC Unit] => % [Air Density] => 0.0842 [Air Density Unit] => lb/cu.ft ) [INSIDE TEMPERATURE] => Array ( [Inside Temperature] => 42.5 [High Inside Temperature] => 43.6 [Time of High Inside Temperature] => 12:00a [Low Inside Temperature] => 42.5 [Time of Low Inside Temperature] => 3:41a [High Monthly Inside Temperature] => 45.4 [Low Monthly Inside Temperature] => 39.4 [High Yearly Inside Temperature] => 45.7 [Low Yearly Inside Temperature] => 39.4 ) [OUTSIDE TEMPERATURE] => Array ( [Outside Temperature] => 15.1 [High Outside Temperature] => 21.7 [Low Outside Temperature] => 15.1 [Time of High Outside Temperature] => 12:00a [Time of Low Outside Temperature] => 4:04a [High monthly Outside Temperature] => 46.1 [Low monthly Outside Temperature] => -11.3 [High yearly Outside Temperature] => 46.1 [Low yearly Outside Temperature] => -12.5 ) . . . )
    2 points
  23. So just to say it, the on event handler is accepting a callback function to run when there is a "play" event. A simpler solution would be to just have a function defined there, that the callback would run, or to define a function globally and pass the name of the function. However, @Kicken coded this function to return an anonymous function. It helps to focus in on return statements in code like this. If you notice the requestSent variable is declared outside the function declaration that does the work. This creates a "closure" (or takes advantage of javascript closure) depending on how you want to think about it. It makes the variable requestSent available to the inner function that is being returned, and this variable will continue to exist in the browser's memory associated with the window/page, until such a time as a new request is made that causes new html/javascript/css to be loaded. An alternative would be to declare requestSent globally and use that, but he gave you something more sophisticated -- a function that returns a function and takes advantage of a variable that is only visible to the anonymous function, and yet is available to the anonymous function across executions. Each time the callback is run, this could be either for the same song or a different song, so inside the function, there is a jQuery call to find the id of the button. let a_id = $(this).attr("id") It's good to think about why this is declared inside the function and how that works. Since this handler can be called for any song, the $(this) resolves in this situation as the song that is being played. Thus the a_id gets set each time there's a play event, and then gets the html id attribute. I added code to push the value onto the requestSent array, which again, since it's part of the closure for the anonymous function, survives across plays. I used Array.includes() to check if the song id already exists in requestSent. If not, I update requestSent with requestSent.push(a_id) and the ajax runs, passing a_id. The ajax is also being done using the jQuery library. The final question you should probably be asking is: if this is a function that returns a function, then how is it, that the callback, which requires a function to run, gets the actual function it needs. A function that returns a function is not a callback. The answer is that again Kicken used an IFFE here. What is actually being passed is a function that is immediately executed. You can see this because after the function definition function () { ... } It is immediately followed by the parens ie. () which causes javascript to execute the function. function () { ... }() So this code works because the function that returns a function, is run immediately, giving the callback parameter what it wants ... a function to run when a play event occurs. The function is anonymous and only bound to the event handler for play events, which also keeps global scope from being cluttered with a symbol table entry for a function that is only needed for the callback. The benefit of doing it this way is that he did not need to utilize a global variable, since closure takes care of this for you. This type of code is favored in many situations, since you don't have a slew of global variables floating around. Nothing outside the callback function can see or modify the requestSent array -- yet it is essentially a private environment that the callback uses. As I said previously -- advanced javascript stuff, that can be confusing if you are still learning javascript. Hope this helps -- using those terms (IFFE, javascript closure, js anonymous function, js callbacks, js this) will lead you to an enormous amount of additional material if you need to explore them further.
    2 points
  24. Keep track of whether or not you've sent the count request, and only send it if you haven't. $('audio').on("play", function(){ let requestSent = false return function(){ if (requestSent){ return; } requestSent = true; let a_id = $(this).attr("id"); $.ajax({ url: "count-play.php?id=" + a_id , success: function(result){ $("."+ a_id + "count").html(result); } }); }; }()); The first time the event fires, requestSent will be false so the ajax call will run and record the play event and requestSent will be set to true. Later events will see that requestSent is true and immediately return thus doing nothing.
    2 points
  25. The PHP DateTime::diff() method provides a very convenient way of getting the days, hours, minutes and seconds components of a time difference so this script uses an AJAX request on loading to get the time remaining. From then on, it calls a javascript function every second to reduce the time displayed by one second. This greatly reduces network traffic and gives a consistent update performance. Repeatedly using AJAX could sometimes result in delays preventing a regular countdown interval. <?php ################################################################################################################## # # # THIS SECTION HANDLES THE AJAX REQUEST AND EXITS TO SEND RESPONSE (Days,hrs, mins, secs remaining) # # # if (isset($_GET['ajax'])) { if ($_GET['ajax'] == 'countdown') { $remain = ['days' => 0, 'hrs' => 0, 'mins' => 0, 'secs' => 0]; $dt1 = new DateTime( $_GET['target'] ); $dt2 = new DateTime('now'); if ($dt1 > $dt2) { $diff = $dt1->diff($dt2); $remain['days'] = $diff->days; $remain['hrs'] = $diff->h; $remain['mins'] = $diff->i; $remain['secs'] = $diff->s; } exit(json_encode($remain)); } } # # ################################################################################################################### $target = '2022-04-30 23:59:59'; // SET OR GET TARGET TIME HERE $targ = new DateTime($target); $target_time = $targ->format('g:ia'); $target_date = $targ->format('F jS Y'); ?> <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Countdown</title> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script type='text/javascript'> var inter $().ready( function() { get_time_remaining() // call AJAX request to get remaining time inter = setInterval(countdown, 1000) // set timer to call "countdown()" function every second }) function countdown() { let s = parseInt($("#secs").html()) // get current time remaining let m = parseInt($("#mins").html()) let h = parseInt($("#hrs").html()) let d = parseInt($("#days").html()) if (d==0 && h==0 && m==0 && s==0) { // exit when target time is reached clearInterval(inter) $(".remain").css("background-color", "red") return } s--; // reduce display by 1 second if (s < 0) { s = 59; m-- } if (m < 0) { m = 59 h-- } if (h < 0) { h = 23 d-- } if (d < 0) { d = 0 } $("#days").html(d) // redisplay new values $("#hrs").html(h) $("#mins").html(m) $("#secs").html(s) } function get_time_remaining() { $.get( // make AJAX request "", {"ajax":"countdown", "target":$("#target").val()}, function(resp) { // put response values in display fields $("#days").html( resp.days ) $("#hrs").html( resp.hrs ) $("#mins").html( resp.mins ) $("#secs").html( resp.secs ) }, "JSON" ) } </script> <style type='text/css'> body { font-family: verdana, sans-serif; font-size: 11pt; } header { padding: 8px; text-align: center; width: 600px; margin: 20px auto; background-color: #F0F0F0; } .target { color: #006EFC; font-size: 16pt; } table { border-collapse: collapse; width: 400px; margin: 0 auto; } td, th { padding: 8px; text-align: center; width: 25%; } .remain { font-size: 24pt; color: white; background-color: black; border: 1px solid white; } </style> </head> <body> <header> <p>Countdown to</p> <p class='target'><?=$target_time?> on <?=$target_date?> </p> <!-- make target time available to javascript --> <input type='hidden' id='target' value='<?=$target?>' > <table border='0'> <tr><th>Days</th><th>Hours</th><th>Mins</th><th>Secs</th></tr> <tr> <td class='remain' id='days'>0</td> <td class='remain' id='hrs'>0</td> <td class='remain' id='mins'>0</td> <td class='remain' id='secs'>0</td> </tr> </table> </header> </body> </html>
    2 points
  26. I don't have any specific recollection of such a thing, but a lot of things have changed in the css world, most notably the standardization of flexbox and grid that make older techniques and tricks of css layout obsolete. You just don't need those things anymore when flexbox or grid can take care of your layout needs with simple, consistent and easy to understand syntax. There was a time when you needed to know the ins and outs of floats and clear fix, and other arcane tricks of css, but that's basically obsolete knowledge. People also use to use tables inside tables inside tables to get their "pixel perfect" layouts, but that also has given way to a focus on creating layouts that adapt from desktop to mobile. This guy (Kevin Powell) has become well known in the css/web design world, and he really knows his stuff. This video covers flexbox. If you work through the examples with him, you will learn what you need. He also has a corresponding Grid video. If you want something more interactive, lots of people love Scrimba, and in particular Per Borgen, who is one of the Scrimba founders. He happens to have a free scrimba course covering grid and flexbox, so that is another way you can learn flexbox, if you want something more interactive. The free Scrimba Grid/Flexbox course is here: https://scrimba.com/learn/cssgrid
    2 points
  27. Just before closing the book on this one, please ask yourself this: In [another] four months time, are you going to look at this code and ask yourself "What the H*** does this do?" You will spend far more time reading code than writing it (accepted industry stats estimate 80% reading, 20% writing). Always favour Clarity and Correctness over Conciseness or Cleverness. Regards, Phill W.
    2 points
  28. It's the antithesis of progress and learning. We can only tell him stuff that he already knows, which is pointless. If he doesn't know it he won't use it. Therefore, whatever we tell him is a waste of time.
    2 points
  29. First, let me just opine that there are generally accepted reasons to create stored procedures. Those include 'performance', 'adding business logic', 'doing things that can't easily be done in a single query/ie having procedural logic', 'providing a procedural api that enforces business rules', and in the case of triggers, enforcing complex data integrity, which is often done with triggers, and can't easily or robustly done client-side. What you have to understand about MySQL, is that it doesn't work the same way that Sybase/MS-SQL Server or Oracle work. In those DB's, sprocs are cached in global server memory, so they can be shared by connections. Oracle also has heavy client connection overhead. MySQL does not work that way. Quite probably, a normal query will be faster with MySQL in many circumstances, when compared with a sproc, because you have to understand that MySQL sprocs are not available in a shared memory structure like Oracle. So performance is not one of the advantages of sprocs in MySQL. The sproc memory exists PER Connection! So that should give you pause, from a performance standpoint, because each connection will need memory allocation for sprocs, and conversely, the fact that clientA is calling a sproc, does absolutely nothing for clientB. There has been rumblings that something might be done about this architecture, but as of MySQL 8, as far as I know the per connection sproc cache is still local. So to be absolutely clear, what happens when you create a connection to MySQL, every time you use a sproc, it gets compiled (if it was not already used), and stored in memory. There is not pre-compilation performance boost you get from other databases like Oracle. Furthermore, PHP is a "shared nothing" environment. Depending on how you are running PHP, database connections will be created/destroyed frequently, or upon every execution. The fact that mysql connections are lightweight and performant is one of the reasons it has always been a good partner for PHP data persistence. This was your original concern. Most of us tried to convince you that you already are covered for those concerns by: Disallowing multiple statements in PDO Using bind variables Using InnoDB with allocation of memory to buffer pools, to maximize cache hit of result set data PHP does give you a robust and highly capable language to build your reporting tool, and your code can be safe and will be performant against mysql, and sprocs bring nothing to the table that will make that better for you. I understand that you have felt frustrated in this conversation, but this is a frequent phenomenon in the tech communities I frequent, when someone comes from a point of view that has predetermined a particular approach is the only way to do it. People immediately question whether or not, as the old adage goes, this is a "person with a hammer, who sees everything as a nail." I think this was a valuable thread that contributed to the community, and I appreciate your perseverance and patience in sticking with it, but I also hope you can see that developers who are donating their time to try and help other developers tend to get a bit irritated when they perceive that someone is telling them "just shutup and answer my question", especially when they aren't convinced that the problem to be solved has been articulated clearly. With that said, I hope you will continue to find the forum valuable to you now and in the future.
    2 points
  30. Doesn't your console have a "preserve" option? Or, add "return false" to the end of your submitData() function to stop the page refreshing
    2 points
  31. Hello everyone, I'm very new to this site. I'm here to learn how to code in PHP as I once did. I'm very raw at tho, and I'm looking to start back up in it again. So again, hello everyone and remember I'm new. So any dummy questions I made ask, please bear with me. I would like to start my own web site for my own purpose. Something very small and for my needs. And to top it all off, I'm going to run it on a Raspberry Pi from my home. This is should be a fun trip. Thanks Sincerely Dan
    2 points
  32. These are the results I get (wordlist contains 351,100 records) $t1 = microtime(1); $res = $db->query("SELECT word FROM wordlist WHERE MATCH (word) AGAINST ('sang*' IN BOOLEAN MODE)"); $t2 = microtime(1); printf('Query 1 : %0.4f seconds<br>', $t2 - $t1); $t1 = microtime(1); $res = $db->query("SELECT word FROM wordlist WHERE word LIKE 'sang%'"); $t2 = microtime(1); printf('Query 2 : %0.4f seconds<br>', $t2 - $t1); results (74 words found) Query 1 : 0.0026 seconds Query 2 : 0.0005 seconds
    2 points
  33. In case anyone comes here and wants to know what the answer was, since that wasn't shared, Problem 1 - phpunit/phpunit[9.3.3, ..., 9.5.x-dev] require ext-dom * -> it is missing from your system. Install or enable PHP's dom extension. - Root composer.json requires phpunit/phpunit ^9.3.3 -> satisfiable by phpunit/phpunit[9.3.3, ..., 9.5.x-dev]. phpunit requires ext-dom (aka the DOM extension) but apparently it's missing. Install it.
    2 points
  34. If you want it in a single query, initialize the variables in a joined subquery SELECT , (@csumA := @csumA + A) as cumulative_A , (@csumM := @csumM + M) as cumulative_M , (@csumE := @csumE + E) as cumulative_E , (@csumW := @csumW + W) as cumulative_W FROM ( SELECT WEEK(s.date) week, SUM(CASE WHEN s.user_id = 50 THEN s.points ELSE 0 END) AS A, SUM(CASE WHEN s.user_id = 51 THEN s.points ELSE 0 END) AS M, SUM(CASE WHEN s.user_id = 52 THEN s.points ELSE 0 END) AS E, SUM(CASE WHEN s.user_id = 53 THEN s.points ELSE 0 END) AS W FROM users u JOIN scores s ON u.user_id = s.user_id JOIN league l ON l.league_id = s.league_id AND and l.league_name = 'Sunday League' WHERE year(s.date) = YEAR(sysdate()) GROUP BY s.date ORDER BY s.date ASC ) PTS JOIN ( SELECT @csumA:=0, @csumM:=0, @csumE := 0, @csumW:=0 ) INIT;
    2 points
  35. Since you want to filter an array, I suggest array_filter() $times = [ '2021-06-02T19:40:00Z', '2021-06-03T02:10:00Z', '2021-06-03T01:10:00Z', '2021-06-02T23:05:00Z', '2021-06-02T23:05:00Z', '2021-06-02T23:07:00Z', '2021-06-02T23:20:00Z', '2021-06-02T18:20:00Z', '2021-06-03T00:10:00Z', '2021-06-03T00:40:00Z' ]; $d = new DateTime('23:59:59', new DateTimeZone('Z')); $newtimes = array_filter($times, function($v) use ($d) { return new DateTime($v) <= $d; });
    2 points
  36. I'll eat my words. I couldn't resist the challenge so, having slept on it, I wrote a an SQL function "isConsecutive(dates)" to find records where there are fewer than 10 dates and they are consecutive. TEST DATA and QUERY TABLE: ahtest +----+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | id | adates | +----+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | 1 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00 | | 2 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-08 12:00,2021-04-10 12:00,2021-04-11 12:00,2021-04-12 12:00,2021-04-13 12:00,2021-04-14 12:00 | | 3 | 2021-04-01 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00,2021-04-10 12:00,2021-04-11 12:00,2021-04-12 12:00 | | 4 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00,2021-04-10 12:00,2021-04-11 12:00 | | 5 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00,2021-04-09 12:00,2021-04-11 12:00,2021-04-12 12:00,2021-04-13 12:00 | | 6 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00,2021-04-09 12:00 | | 7 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-06 12:00,2021-04-08 12:00,2021-04-09 12:00,2021-04-11 12:00,2021-04-12 12:00,2021-04-13 12:00 | | 8 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00 | | 9 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00,2021-04-09 12:00,2021-04-11 12:00,2021-04-13 12:00,2021-04-15 12:00 | | 10 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-08 12:00,2021-04-09 12:00,2021-04-10 12:00,2021-04-11 12:00,2021-04-13 12:00,2021-04-14 12:00 | | 11 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-04 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00,2021-04-09 12:00,2021-04-10 12:00,2021-04-11 12:00,2021-04-12 12:00,2021-04-13 12:00,2021-04-14 12:00 | | 12 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-09 12:00,2021-04-10 12:00,2021-04-11 12:00,2021-04-12 12:00 | | 13 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00,2021-04-09 12:00,2021-04-10 12:00,2021-04-11 12:00,2021-04-13 12:00 | | 14 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00 | | 15 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00,2021-04-09 12:00,2021-04-10 12:00,2021-04-11 12:00 | | 16 | 2021-04-01 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00,2021-04-10 12:00,2021-04-11 12:00 | | 17 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00,2021-04-09 12:00,2021-04-10 12:00,2021-04-11 12:00 | | 18 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00 | | 19 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00,2021-04-10 12:00 | | 20 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-06 12:00,2021-04-08 12:00,2021-04-10 12:00,2021-04-11 12:00,2021-04-12 12:00,2021-04-13 12:00,2021-04-14 12:00,2021-04-15 12:00 | +----+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ mysql> SELECT id -> , adates -> FROM ahtest -> WHERE isConsecutive(adates); +----+-----------------------------------------------------------------------------------------------------------------------------------------+ | id | adates | +----+-----------------------------------------------------------------------------------------------------------------------------------------+ | 1 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00 | | 8 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00 | | 14 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00 | | 18 | 2021-04-01 12:00,2021-04-02 12:00,2021-04-03 12:00,2021-04-04 12:00,2021-04-05 12:00,2021-04-06 12:00,2021-04-07 12:00,2021-04-08 12:00 | +----+-----------------------------------------------------------------------------------------------------------------------------------------+ THE FUNCTION DELIMITER $$ CREATE FUNCTION `isConsecutive`(dates varchar(255)) RETURNS int(11) BEGIN DECLARE k INTEGER DEFAULT 1; DECLARE da DATE DEFAULT SUBSTRING_INDEX(dates, ',', 1); DECLARE db DATE ; DECLARE num INTEGER DEFAULT (LENGTH(dates)+1) DIV 17; DECLARE strx VARCHAR(255) DEFAULT SUBSTRING_INDEX(dates, ',', -(num-k)); DECLARE isconsec INTEGER DEFAULT 1; IF num >= 10 THEN RETURN 0; END IF; WHILE LENGTH(strx) > 0 DO SET db = SUBSTRING_INDEX(strx, ',', 1); if DATEDIFF(db, da) <> 1 THEN SET isconsec = 0; END IF; SET k = k + 1; SET da = SUBSTRING_INDEX(strx, ',', 1); SET strx = SUBSTRING_INDEX(strx, ',', -(num-k)); END WHILE; RETURN isconsec; END$$ DELIMITER ;
    2 points
  37. try foreach ($array as $k => $d) { if ($k > 0) { if (strtotime($d) > strtotime($array[$k-1])+6) { $new[] = "-------------------"; } } $new[] = $d; } $new = Array ( [0] => 2021-02-10 09:04:48 [1] => 2021-02-10 09:04:54 [2] => 2021-02-10 09:05:00 [3] => 2021-02-10 09:05:06 [4] => 2021-02-10 09:05:12 [5] => 2021-02-10 09:05:18 [6] => ------------------- [7] => 2021-02-10 09:06:18 [8] => 2021-02-10 09:06:24 ) [edit...] Alternative solution... $new = []; $newkey = 0; foreach ($array as $k => $d) { if ($k > 0) { if (strtotime($d) > strtotime($array[$k-1])+6) { $newkey++; } } $new[$newkey][] = $d; } gives $new = Array ( [0] => Array ( [0] => 2021-02-10 09:04:48 [1] => 2021-02-10 09:04:54 [2] => 2021-02-10 09:05:00 [3] => 2021-02-10 09:05:06 [4] => 2021-02-10 09:05:12 [5] => 2021-02-10 09:05:18 ) [1] => Array ( [0] => 2021-02-10 09:06:18 [1] => 2021-02-10 09:06:24 ) )
    2 points
  38. $this (programming pun intended) is the correct syntax, but produced a different error than the one you posted about the undefined variable. what was the error message in $this case? i'm going to guess that the database connection probably failed and there's no useful error handling in the code. while not the cause of the most immediate problem, your main code should be responsible for creating the database connection, then use dependency injection to supply that to any class that needs it. by making each class responsible for getting a specific database connection, your code is not general purpose. if the data source changes, to use an additional/different database type or using a remote api, you would need to go through and edit all the current code.
    2 points
  39. I tried Googling charts.js to have a look at their API documentation. What I found was nothing like the formats that you appear to be using. I did manage to get a chart produced using google.visualization api (if that helps) <?php $getdata = ' { "result": [ { "ID": 1, "Users": [ { "UserObject": { "UserName": "User1", "-": { "ID": 1 }, "0": "0" }, "User": "User1", "Amount": 10 }, { "UserObject": { "UserName": "User2", "-": { "ID": 1 }, "0": "0" }, "User": "User2", "Amount": 20 }, { "UserObject": { "UserName": "User3", "-": { "ID": 1 }, "0": "0" }, "User": "User3", "Amount": 15 } ], "Reached": false, "IsActive": true } ], "error": false, "version": 1 } '; $data = json_decode($getdata); $users = $data->result[0]->Users; $dataPoints = array( ['User', 'Amount'] ); foreach($users as $user): $dataPoints[] = array( $user->User, $user->Amount ); endforeach; $jdata = json_encode($dataPoints); ?> <!DOCTYPE HTML> <html> <head> <title>Test</title> <meta http-equiv="content-language" content="en"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script> <script type='text/javascript'> $().ready(function() { google.charts.load('current', {'packages':['corechart']}); google.charts.setOnLoadCallback(drawChart); // Draw the chart and set the chart values function drawChart() { var dataArray = JSON.parse($("#chart-values").val()) var data = google.visualization.arrayToDataTable(dataArray); // Optional; add a title and set the width and height of the chart var options = { 'title':'User Amounts', 'width':550, 'height':400, 'slices': { 0: {'color':'#2ecc71' }, 1: {'color':'#3498db' }, 2: {'color':'#95a5a6' }, 3: {'color':'#9b59b6' }, 4: {'color':'#f1c40f' }, 5: {'color':'#e74c3c' }, 6: {'color':'#34495e' } } }; // Display the chart inside the <div> element with id="piechart" var chart = new google.visualization.PieChart(document.getElementById('myChart')); chart.draw(data, options); } }) </script> <style> .container { width: 80%; margin: 15px auto; } </style> </head> <body> <input type='hidden' id='chart-values' value='<?=$jdata?>'> <div class="container"> <h2>Pie Chart Demo</h2> <div id="myChart"></div> </div> </body> </html>
    2 points
  40. if ($success) { $_SESSION["userLoggedIn"] = $username; header("Location:index.php"); }else{ $error = $account->getError(Constants::$registerFailed); } It's a good practice to use an exit after the header ("Location ...
    2 points
  41. 1 and 2 would presumably be input from the web page. The rest would be something like: for ($m=1; $m<=$M; $m++) { for ($l=1; $l<=$L; $l++) { for ($j=1; $j<=$N; $j++) { #do calculation here storing it in a 2D array } # select minimum here (perhaps min() function) } } # use array sort # use PHP vector class # compute distance from vectors # echo results in desired format
    2 points
  42. If it helps, note that that a <button> element can have a value attribute independent of its label <?php $option = $_GET['option'] ?? ''; if ($option) echo "You chose $option<hr>"; ?> <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Sample</title> </head> <body> <form> Select an option <button name="option" value="1">Choose me</button> <button name="option" value="2">Choose me</button> <button name="option" value="3">No, Choose me</button> <button name="option" value="4">No, Choose me</button> <button name="option" value="5">No, Choose me</button> </form> </body> </html>
    2 points
  43. I just didn't see the table - the end of that first line was somewhere in my neighbour's living room.
    2 points
  44. 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>
    2 points
  45. Don't do that. Not in the actual table at least. Some people recommend this stupidity to try and avoid name collisions in their queries (such as two tables have a Label column) but such issues can be easily handled using the table.column syntax in your query rather than cluttering up column names in the table. SELECT o.Label as o_label, s.Label as s_label FROM order o INNER JOIN status s ON s.Id=o.Status One of the applications I work on was original designed using a scheme like that where every column has a table specific prefix to it and it's super annoying (long names, broken autocomplete) for no real benefit. I've been slowly undoing that when I can and just giving the columns nice simple names. I'd also suggest just using the full table name in your constraint names rather than some alias. It makes things very clear when someone 6 months later needs to decipher things.
    2 points
  46. For example, https://www.php.net/manual/en/datetime.createfromformat.php https://www.php.net/manual/en/datetime.format.php
    2 points
  47. Christmas has come early! <?php const IMGDIR = 'images/'; const THUMBDIR = 'thumbs/'; const THUMBSIZE = 150; // max thumbnail dimension const NUM = 100; // number of images to be processed on each run $images = glob(IMGDIR.'{*.png,*.jpg}', GLOB_BRACE); $thumbs = glob(THUMBDIR.'{*.png,*.jpg}', GLOB_BRACE); // reduce to basenames only $images = array_map('basename', $images); $thumbs = array_map('basename', $thumbs); // copy the next NUM images to $todo list where thumbnails do not yet exist $todo = array_slice(array_diff($images, $thumbs), 0, NUM); $output = ''; foreach ($todo as $fn) { $sz = getimagesize(IMGDIR.$fn); if ($sz[0] == 0) continue; // not an image $ok = 0; $out = null; switch ($sz['mime']) { // check the mime types case 'image/jpeg': $im = imagecreatefromjpeg(IMGDIR.$fn); $ok = $im; $out = 'imagejpeg'; break; case 'image/png': $im = imagecreatefrompng(IMGDIR.$fn); $ok = $im; $out = 'imagepng'; break; default: $ok = 0; } if (!$ok) continue; // not png or jpg // calculate thumbnail dimensions if ($sz[0] >= $sz[1]) { // landscape $w = THUMBSIZE; $h = THUMBSIZE * $sz[1]/$sz[0]; } else { // portrait $h = THUMBSIZE; $w = THUMBSIZE * $sz[0]/$sz[1]; } // copy and resize the image $tim = imagecreatetruecolor(THUMBSIZE, THUMBSIZE); $bg = imagecolorallocatealpha($tim,0xFF,0xFF,0xFF,127); imagefill($tim, 0, 0, $bg); imagecolortransparent($tim, $bg); // centre the image in the 150 pixel square $dx = (THUMBSIZE - $w) / 2; $dy = (THUMBSIZE - $h) / 2; imagecopyresized($tim, $im, $dx, $dy, 0, 0, $w, $h, $sz[0], $sz[1]); imagesavealpha($tim, true); $out($tim, THUMBDIR.$fn); imagedestroy($im); imagedestroy($tim); $output .= "<img src='".THUMBDIR."$fn' alt='$fn'>\n"; } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="content-language" content="en"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Create Thumbnails</title> <meta name="author" content="Barry Andrew"> <meta name="creation-date" content="10/09/2019"> <style type="text/css"> body { font-family: verdana, sans-serif; font-size: 11pt; } header { background-color: black; color: white; padding: 15px 10px;} img { margin: 5px; } </style> </head> <body> <header> <h1>New Thumbnail Images</h1> </header> <?=$output?> </body> </html>
    2 points
  48. This example uses glob() to get all .png and .jpg in a folder. By default, the folder is assumed to be named "images" and is a subdirectory of the folder containing the script. Images are displayed as thumbnails, 5 in each row with 25 per page. <?php session_start(); const IMGDIR = 'images/'; const PERPAGE = 25; $page = $_GET['page'] ?? 1; $imgdir = $_GET['dir'] ?? IMGDIR; if (!isset($_SESSION['imgdir']) || $_SESSION['imgdir'] != $imgdir) { unset($_SESSION['images']); $_SESSION['imgdir'] = $imgdir; $page = 1; } if (!isset($_SESSION['images'])) { $_SESSION['images'] = glob($imgdir.'{*.png,*.jpg}', GLOB_BRACE); // get .jpg and .png images } $total = count($_SESSION['images']); /** ************************************************************************************** * display paginated images from SESSION['images] * * @param int $page * @param int $perpage */ function displayImages($page, $perpage) { $start = ($page - 1) * $perpage; $ilist = array_slice($_SESSION['images'], $start, $perpage); foreach ($ilist as $i) { $n = trim(basename($i)); list($iw, $ih,, $sz) = getimagesize($i); if ($iw >= $ih) { // landscape $w = 150; $h = 150 * $ih/$iw; } else { // portrait $h = 150; $w = 150 * $iw/$ih; } $alt = substr($n, 0, 15); echo " <div class='image'> <img src='$i' height='$h' width = '$w' alt='$alt'> </div> "; } echo "<div style='clear:both'></div>"; } /** ************************************************************************************ * function to output page selection buttons * * @param int $total total records * @param int $page current page number * @return string selection buttons html */ function page_selector($total, $page) { if ($total==0) { return ''; } $kPages = ceil($total/PERPAGE); $filler = '&nbsp;&middot;&nbsp;&middot;&nbsp;&middot;&nbsp;'; $lim1 = max(1, $page-2); $lim2 = min($kPages, $page+3); $p = $page==1 ? 1 : $page - 1; $n = $page== $kPages ? $kPages : $page + 1;; $out = "$kPages page" . ($kPages==1 ? '' : 's') . " &emsp;"; if ($kPages==1) { return $out; } $out .= ($page > 1) ? "<div class='pagipage' data-pn='$p'>Prev</div>&ensp;" : "<div class='pagipage x' data-pn='$p' disabled>Prev</div>&ensp;"; if ($page > 4) { $out .= "<div class='pagipage' data-pn='1'>1</div> $filler"; } elseif ($page==4) { $out .= "<div class='pagipage' data-pn='1'>1</div>"; } for ($i=$lim1; $i<=$lim2; $i++) { if ($page==$i) $out .= "<div class='pagicurrent'>$i</div>"; else $out .= "<div class='pagipage' data-pn='$i'>$i</div>"; } if ($page < $kPages-3) { $out .= "$filler <div class='pagipage' data-pn='$kPages'>$kPages</div>"; } $out .= $page < $kPages ? "&ensp;<div class='pagipage' data-pn='$n'>Next</div>" : "&ensp;<div class='pagipage x' data-pn='$n' disabled>Next</div>"; return $out; } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="content-language" content="en"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="author" content="B A Andrew"> <meta name="creation-date" content="11/29/2019"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <title>Example</title> <script type="text/javascript"> $().ready( function() { $(".pagipage").click( function() { $("#page").val( $(this).data("pn") ) $("#form1").submit() }) }) </script> <style type="text/css"> body { font-family: verdana, sans-serif; font-size: 11pt; } label { display: inline-block; width: 150px; font-weight: 600; } #image_wrapper { margin: 30px; } .image { width: 18%; min-height: 200px; margin: 10px; float: left; text-align: center; padding: auto;} /* pagination styles */ .pagipage { display: inline; width: 25px; height: 15px; padding: 3px 5px; text-align: center; font-size: 9pt; border: 1px solid #BB9A21 ; color: #BB9A21; background-color: #FFF; cursor: pointer; margin-left: -1px; } .pagipage.x { background-color: #CCC;} .pagipage:hover { background-color: #BB9A21; border-color: #F0F; color: white; } .pagicurrent { display: inline; width: 25px; height: 15px; text-align: center; font-size: 9pt; font-weight: 600; border: 1px solid #BB9A21; background-color: #BB9A21; color: white; padding: 3px 5px; } .paginate_panel { text-align: center; margin: 20px 0; width: 100%; color: #BB9A21; } </style> </head> <body> <header> <h1>Example Image List</h1> </header> <form id="form1"> <fieldset> <label>Image Folder</label> <input type="text" name="dir" value="<?=$imgdir?>" size="80"> <input type="hidden" name="page" id="page" value="<?=$page?>"> <br> <label>&nbsp;</label> <input type="submit" name="btnSubmit" value="Submit"> </fieldset> </form> <div class='paginate_panel'> <?=page_selector($total, $page, PERPAGE)?> </div> <div id="image_wrapper"> <?=displayImages($page, PERPAGE)?> </div> <div class='paginate_panel'> <?=page_selector($total, $page, PERPAGE)?> </div> </body> </html>
    2 points
  49. You need to specify your units for the margin values. 161px, not just 161.
    2 points
This leaderboard is set to New York/GMT-04:00
×
×
  • 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.