Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 09/23/2012 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. the code is doing exactly what it was written to do, build a <tr><td>num</td></tr> for each number. if you want to produce a single <tr></tr>, you would need to add the opening <tr> before the start of the looping and add the closing </tr> after the end of the looping.
    2 points
  17. The main problem is that this $email_to = "email1@website.com", "email2@whatever.com"; isn't going to work. You can't just list multiple email address strings like that. But before that, the other problem is that you're manually trying to send emails. That's almost always bad: emails are hard, and doing it yourself is pretty much always going to go badly. Switch to a library like PHPMailer or SwiftMailer, which will not only be able to do emails properly but also make it easier to do things like add multiple recipients.
    2 points
  18. 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. None. I played around with ChatGPT a bit when it first came out, to see what it was capable of and just have some fun. I was impressed by it's ability to understand things. I fed it a few functions I've written and asked it to explain what the functions did and write sample code using the functions and it was surprisingly accurate. I don't really see much use for it day-to-day though, so I haven't really used it in quite a while. It does get a lot closer to the "Ask a question, get an answer" goal of search engines, which is why I immediately knew people would be working on that and am not at all surprised to see it happening. Eventually as the models get better and more integrated into search, you'll be able to just type a plain-English (or whatever language) question into google and get an actually answer back instead of having to wade through a list of result pages. From the code side of things, the AI is good enough right now to answer simple syntax / logic errors. Take one of the questions posted here as an example. I told ChatGPT what the error was, what the code was, and to tell me why. It responded: I imagine eventually such a tool will be used to help teach new programmers by either providing better error detection in IDE's or having an virtual mentor they can ask questions and get immediate answers rather than having to either search the web or post on a forum and wait for a response. There are already AI coding assistants that might fulfill this task, I haven't tried any of them personally to know how useful they are.
    2 points
  21. 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
  22. 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
  23. FYI - ROLLUP is certainly available in version 5.7 mysql> SELECT VERSION(); +------------+ | VERSION() | +------------+ | 5.7.36-log | +------------+ mysql> SELECT classid as class -> , COUNT(*) as students -> FROM student_class -> WHERE semesterid = 12 -> GROUP BY classid WITH ROLLUP; +-------+----------+ | class | students | +-------+----------+ | 1 | 17 | | 2 | 18 | | 3 | 20 | | 4 | 23 | | 5 | 22 | | 6 | 27 | | 7 | 24 | | 8 | 20 | | 9 | 21 | | 10 | 27 | | 11 | 25 | | 13 | 5 | | 14 | 5 | | 16 | 3 | | 17 | 5 | | 19 | 17 | | NULL | 279 | <--- ROLLUP total +-------+----------+
    2 points
  24. Depending on what it is you're trying to do with the data, there are several ways to change a field. You can set up an accessor or mutator or use a query scope, for instance. Query scope sounds like what you're looking for, although should worse comes to worst you could just write a trait and use it on your model instances where needed.
    2 points
  25. Simple. Triple the page width and offset each label. require 'code128.php'; $data = ['item_name' => 'Fuel Vapour Hose' ,'code_purchase' => 'ABC-2342' ,'code_sale' => 'DFS-4312' ,'item_code' => '47900001' ]; class Barcode_Label extends PDF_Code128 { protected $data; //constructor public function __construct() { parent::__construct('L','mm',[190, 35]); } public function printLabel($data) { $this->setMargins(5,5,5); $this->SetAutoPageBreak(0); $this->AddPage(); $this->setFont('Times', 'B', 10); for ($lab=0; $lab<3; $lab++) { $offset = $lab * 65; $this->setXY($offset, 5); $this->Cell(50, 5, $data['item_name'], 0, 2, 'C'); $this->Cell(25, 5, $data['code_purchase'], 0, 0, 'C'); $this->Cell(25, 5, $data['code_sale'], 0, 2, 'C'); $barcode = $this->Code128($offset + 5,15,$data['item_code'],50,10); $this->setXY($offset, 25); $this->Cell(50, 5, $data['item_code'], 0, 1, 'C'); } } } #Barcode_Label $label= new Barcode_Label(); for ($i=0; $i<3; $i++) { $label->printLabel($data); } $label->Output(); [edit] PS I don't know your label dimensions so you may have to adjust offset, page size and margins
    2 points
  26. First only returns a single item, so there's no point in putting it in a collection. The collection is for methods that might return several items.
    2 points
  27. @gizmola and I both gave you code that you have not implemented. You should spend some time going through this PDO tutorial. Making a PDO connection is one of the simplest things you would ever need to do. https://phpdelusions.net/pdo This is all that is required to make a PDO connection. Anything you do beyond this, you should know exactly WHY you are doing more. $con = new PDO("mysql:host=localhost;dbname=test", 'root', '');
    2 points
  28. 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
  29. Using a DB, I'd do it this way (tables used are from my SQL tutorial). Select a house name and the pupils menu lists pupils from that house. <?php const HOST = 'localhost'; const USERNAME = '????'; const PASSWORD = '????'; const DATABASE = 'jointute'; // default db $db = pdoConnect(); //============================================================================== // HANDLE AJAX CALLS // if (isset($_GET['ajax'])) { if ($_GET['ajax']=='pupilopts') { exit( json_encode(pupilOptions($db, $_GET['hid']))); } exit('INVALID REQUEST'); } //============================================================================== function houseOptions($db) { $opts = "<option value=''>- select house -</option>\n"; $res = $db->query("SELECT houseID , house_name FROM house ORDER BY house_name "); foreach ($res as $r) { $opts .= "<option value='{$r['houseID']}'>{$r['house_name']}</option>\n"; } return $opts; } function pupilOptions($db, $hid) { $opts = []; $res = $db->prepare("SELECT pupilID , CONCAT(lname, ', ', fname) as name FROM pupil WHERE houseID = ? ORDER BY lname, fname "); $res->execute([$hid]); $pups = $res->fetchAll(); $opts = array_column($pups, 'name', 'pupilID'); sort($opts); return $opts; } 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); return $db; } ?> <!DOCTYPE html> <html lang='en'> <head> <title>Example</title> <meta charset='utf-8'> <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script type='text/javascript'> $().ready( function() { $("#houses").change( function() { var hid = $(this).val() $.get( "", // specify processing file on server (in this case it's same file) {"ajax":"pupilopts", "hid":hid}, // data to send in request function(resp) { // handle the response $("#pupils").html("<option value=''> - select pupil -</option"); $.each(resp, function(k, v) { $("#pupils").append($("<option>", {"val":k, "text":v})) }) }, "JSON" // response type ) }) }) </script> <style type='text/css'> body { font-family: calibri, sans-serif; font-size: 12pt; } div { margin: 16px; padding: 8px; border: 1px solid gray; } label { display: inline-block; background-color: black; color: white; width: 120px; padding: 8px; margin: 1px 8px; } </style> </head> <body> <div> <label>House</label> <select id="houses" > <?= houseOptions($db) ?> </select> </div> <div> <label>Pupil</label> <select id="pupils" > <!-- pupil options --> </select> </div> </body> </html>
    2 points
  30. 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
  31. This fails $j = "{'admin': 1, 'moderator': 1}" ; $a = json_decode($j, 1); echo '<pre> a ' . print_r($a, 1) . '</pre>'; This works $j = '{"admin": 1, "moderator": 1}' ; $b = json_decode($j, 1); echo '<pre> b ' . print_r($b, 1) . '</pre>'; Note the quotes in the JSON string.
    2 points
  32. You've fixed things but you haven't fixed things. Like these: if(isset($_POST['d_name'])){ } if(isset($_POST['manner_death'])){ } if(isset($_POST['place_death'])){ } if(isset($_POST['nok'])){ } if(isset($_POST['rel_nok'])){ } if(isset($_POST['morgue_att'])){ } What are those doing? Nothing. They don't do anything. Then you have if(isset($_POST['tag_num'])){ if(isset($_POST['treatment'])) The first line makes sense, but the second? Without a pair of { } then it will only run the very first line of code that comes after: the assignment for $d_name. Then in your query, $query = "insert into data ( d_name, manner_death, place_death ,nok, rel_nok, morgue_att, tag_num, treatment) values ( '$d_name'.'$manner_death','$place_death','$nok','$rel_nok','$morgue_att','$tag_num','$treatment')"; you managed to fix the one syntax error but you created a new one. You cannot create websites by putting code in your editor and hoping everything will work. You have to make actual, conscious, deliberate decisions about the code. You have to know what different pieces of code mean. You have to understand why code is what it is and then how you can use it to accomplish what you want. So before you try to write more code, stop and take a few days to learn what you can about PHP. Then come back to this file and put some thought into each line of code in it.
    2 points
  33. There is a very easy way to do this using a MySql myisam table. Store each vote in a table like this... CREATE TABLE `vote` ( `username` varchar(50) NOT NULL, `vote_year` year(4) NOT NULL, `week_num` tinyint(4) NOT NULL, `vote_count` int(11) NOT NULL AUTO_INCREMENT, `time_voted` datetime DEFAULT CURRENT_TIMESTAMP, `voted_for` int(11) DEFAULT NULL COMMENT 'Who/whatever was voted for', PRIMARY KEY (`username`,`vote_year`,`week_num`,`vote_count`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; Note the last column of the primary key is the auto-increment column "vote_count". This will make the vote count start again at 1 for each username each week whe you add votes. mysql> INSERT INTO vote (username, vote_year, week_num, voted_for) VALUES -> ('user1', year(curdate()), weekofyear(curdate()), 1), -> ('user1', year(curdate()), weekofyear(curdate()), 20), -> ('user1', year(curdate()), weekofyear(curdate()), 5), -> ('user2', year(curdate()), weekofyear(curdate()), 5), -> ('user2', year(curdate()), weekofyear(curdate()), 1), -> ('user2', year(curdate()), weekofyear(curdate()), 3); Query OK, 6 rows affected (0.00 sec) mysql> select * from vote; +----------+-----------+----------+------------+---------------------+-----------+ | username | vote_year | week_num | vote_count | time_voted | voted_for | +----------+-----------+----------+------------+---------------------+-----------+ | user1 | 2021 | 24 | 1 | 2021-06-16 17:37:56 | 1 | | user1 | 2021 | 24 | 2 | 2021-06-16 17:37:56 | 20 | | user1 | 2021 | 24 | 3 | 2021-06-16 17:37:56 | 5 | | user2 | 2021 | 24 | 1 | 2021-06-16 17:37:56 | 5 | | user2 | 2021 | 24 | 2 | 2021-06-16 17:37:56 | 1 | | user2 | 2021 | 24 | 3 | 2021-06-16 17:37:56 | 3 | +----------+-----------+----------+------------+---------------------+-----------+ 6 rows in set (0.00 sec) To do the insert in PHP $stmt = $pdo->prepare("INSERT INTO vote (username, vote_year, week_num, voted_for) VALUES ( ?, year(curdate()), weekofyear(curdate()), ? ) "); $stmt->execute( [ $username, $votedFor ] ); Now it doesn't matter how many times a user votes. When you come to counting the votes for each "voted_for" just ignore all records whose vote_count is > 10 SELECT voted_for , count(*) as votes FROM vote WHERE vote_count <= 10 GROUP BY voted_for ORDER BY votes DESC
    2 points
  34. 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
  35. TIP: If you are creating home-grown charts, plotting the values is the easy bit. 95% of the coding effort will be in the drawing of chart area, plot area, axes, axis labels, scaling, titles etc. You can sidestep this with a simple table with horizontal bars. EG CODE EXAMPLE... <?php $values = [ 'Strongly Disagree' => 7, 'Disagree' => 10, 'Neither' => 12, 'Agree' => 25, 'Strongly Agree' => 41 ]; function valueChart(&$values) { $out = "<table class='chartTable'> <tr><th>Response</th> <th>Total</th> <th>Percent</th> </tr> "; $totalVal = array_sum($values); foreach ($values as $resp => $n) { $out .= "<tr><td>$resp</td> <td class='ra'>$n</td> <td>" . bar($n / $totalVal * 100) . "</td></tr>\n"; } $out .= "</table\n"; return $out; } function bar($val=0) { $a = '#3399ff'; $b = '#e6f2ff'; $c = '#0066cc'; $bg = '#eee'; $width = 300; $height = 25; $svg = <<<SVG <svg width='$width' height='$height' viewBox='0 0 $width $height'>"; <defs> <linearGradient id="bargrad" x1="0" y1="0" x2="0" y2="1"> <stop offset="0%" style="stop-color:$a"/> <stop offset="25%" style="stop-color:$b"/> <stop offset="100%" style="stop-color:$c"/> </linearGradient> </defs> <rect x='0' y='0' width='$width' height='$height' style='fill:$bg' stroke='#999'/> SVG; $w = $val/100 * $width; $svg .= "<rect x='0' y='0' width='$w' height='$height' style='fill:url(#bargrad)' />"; $svg .= "</svg>\n"; return $svg; } ?> <!DOCTYPE html> <html lang="en"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Chart Example</title> <head> <style type='text/css'> .chartTable { font-family: arial, sans-serif; font-size: 11pt; } th { padding: 4px 16px ; } td { padding: 0 16px; } .ra { text-align: right; } </style> </head> <body> <?=valueChart($values)?> </body> </html> Hope this helps.
    2 points
  36. That's why I laid it out the way I did with the comments - so it would be easy for you get the separate feet/inches values if you still wanted to go that way. [edit] Look more closely at my code - you require two substring_index()s to extract the inches. The inner to get the string before the final " and the outer one to get the string after the ' SET feet = substring_index(@height, '\'', 1) * 12 , inches = substring_index(substring_index(@height, '"', 1), '\'', -1)
    2 points
  37. Meanwhile, here's an alternative solution to my previous one, this one without the SQL variables. SELECT SUM(CASE WHEN DATE(datein) > DATE(dateout) THEN DATEDIFF(datein, dateout) - 1 ELSE 0 END ) as tot_absent FROM ( SELECT a.dateout , MIN(b.datein) as datein FROM ajoo_login a LEFT JOIN ajoo_login b ON a.dateout < b.datein GROUP BY a.dateout ) logins; +------------+ | tot_absent | +------------+ | 327 | +------------+
    2 points
  38. $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.
    2 points
  39. 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 ...
    2 points
  40. Defining a value in the parameter list makes that parameter optional. If it's not provided when the function is called, the it takes on the value assigned to it. Your specific example doesn't really make use of the feature effectively. Take something like this for example though: function findFiles($directory, $includeHidden = false){ $iter = new DirectoryIterator($directory); $list = []; foreach ($iter as $item){ if ($item->isFile()){ $isHidden = $item->getFilename()[0] === '.'; if ($includeHidden || !$isHidden){ $list[] = $item->getPathname(); } } } return $list; } That function requires at least one parameter when it's called, the directory to search. So you end up with the following options for calling it $files = findFiles('/home/kicken'); /* executes with $directory = '/home/kicken', $includeHidden = false */ $files = findFiles('/home/aoeex', true); /* executes with $directory = '/home/aoeex', $includeHidden = true */
    2 points
  41. I just didn't see the table - the end of that first line was somewhere in my neighbour's living room.
    2 points
  42. 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
  43. An alternative to the 2-table option is to treat costs as transactions, just like payments (cost amounts +ve, payment amounts -ve in this example)... DATA TABLE: payment +------+------+------------+--------------+---------+ | uid | name | trans_date | payment_type | payment | +------+------+------------+--------------+---------+ | 1 | kim | 2020-03-01 | cost | 100 | | 1 | kim | 2020-03-02 | card | -100 | | 2 | lee | 2020-03-01 | cost | 95 | | 2 | lee | 2020-03-02 | cash | -95 | | 3 | kent | 2020-03-01 | cost | 100 | | 3 | kent | 2020-03-03 | cash | -50 | | 3 | kent | 2020-03-04 | card | -50 | | 4 | iya | 2020-03-01 | cost | 80 | | 4 | iya | 2020-03-05 | cash | -40 | | 4 | iya | 2020-03-06 | card | -20 | +------+------+------------+--------------+---------+ then SELECT uid , name , date , cost , cash , card , total as balance FROM ( SELECT name , DATE_FORMAT(trans_date, '%b %D') as date , CASE payment_type WHEN 'cash' THEN -payment ELSE '-' END as cash , CASE payment_type WHEN 'card' THEN -payment ELSE '-' END as card , CASE payment_type WHEN 'cost' THEN payment ELSE '-' END as cost , @tot := CASE @previd WHEN uid THEN @tot+payment ELSE payment END as total , @previd := uid as uid FROM ( SELECT * FROM payment ORDER BY uid, trans_date ) sorted JOIN (SELECT @previd:=0, @tot:=0) initialize ) recs; +------+------+---------+------+------+------+---------+ | uid | name | date | cost | cash | card | balance | +------+------+---------+------+------+------+---------+ | 1 | kim | Mar 1st | 100 | - | - | 100 | | 1 | kim | Mar 2nd | - | - | 100 | 0 | | 2 | lee | Mar 1st | 95 | - | - | 95 | | 2 | lee | Mar 2nd | - | 95 | - | 0 | | 3 | kent | Mar 1st | 100 | - | - | 100 | | 3 | kent | Mar 3rd | - | 50 | - | 50 | | 3 | kent | Mar 4th | - | - | 50 | 0 | | 4 | iya | Mar 1st | 80 | - | - | 80 | | 4 | iya | Mar 5th | - | 40 | - | 40 | | 4 | iya | Mar 6th | - | - | 20 | 20 | +------+------+---------+------+------+------+---------+
    2 points
  44. For example, https://www.php.net/manual/en/datetime.createfromformat.php https://www.php.net/manual/en/datetime.format.php
    2 points
  45. 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
  46. Not even close. This code... $product_details = "SELECT * FROM product WHERE product_id=".$_GET['product_id']; $prepare = $connect->prepare($product_details); $prepare->execute(); ...would embed any SQL injection code contained in the GET into the query which would then be executed. (Just as an unprepared query would) In the correct version the injection code would only be treated as data and not part of the SQL code.
    2 points
  47. the path being used in the opendir() statement either has a hard-coded '/home/sites/' in it or is using a variable that has that incorrect value in it. based on the path where the code is actually at, that part of the path should be - /home/customer/www/
    2 points
  48. I have been playing around with a possible database solution to your problem Given that a postcode such as "EH12 3AB" breaks down into four parts viz +------+----------+--------+------+ | area | district | sector | unit | +------+----------+--------+------+ | EH | 12 | 3 | AB | +------+----------+--------+------+ ... I was toying with this table structure CREATE TABLE `postcode` ( `pc_id` int(11) NOT NULL AUTO_INCREMENT, `seller` int(11) DEFAULT NULL, `area` varchar(2) DEFAULT NULL, `district` varchar(2) DEFAULT NULL, `sector_min` char(1) DEFAULT NULL, `sector_max` char(1) DEFAULT NULL, `unit_min` char(2) DEFAULT NULL, `unit_max` char(2) DEFAULT NULL, `deliverable` tinyint(4) DEFAULT NULL, `price` decimal(8,2) DEFAULT NULL, PRIMARY KEY (`pc_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-------+--------+------+----------+------------+------------+----------+----------+-------------+-------+ | pc_id | seller | area | district | sector_min | sector_max | unit_min | unit_max | deliverable | price | +-------+--------+------+----------+------------+------------+----------+----------+-------------+-------+ | 1 | 1 | EH | 1 | 1 | 4 | AA | ZZ | 1 | 1.50 | | 2 | 1 | EH | 1 | 5 | 5 | AA | BZ | 1 | 1.80 | | 3 | 1 | EH | 1 | 5 | 5 | CA | ZZ | 0 | 2.00 | | 4 | 1 | EH | 2 | 1 | 9 | AA | ZZ | 1 | 2.25 | | 5 | 1 | EH | 3 | 1 | 9 | AA | PZ | 1 | 2.50 | +-------+--------+------+----------+------------+------------+----------+----------+-------------+-------+ My code was $postcodes = [ 'EH1 2DB', 'eh15bg' , 'eh1 5ba', 'eh15dg', 'EH2 7HJ', 'EH3 2PT', 'EH3 8SX', 'EH146DE' ]; echo '<pre>'; foreach ($postcodes as $pc) { vprintf('%s%s %s%s : %s<br>', deliveryPrice($db, $pc)); } echo '</pre>'; function deliveryPrice($db, $pcode) { $pcode = strtoupper(str_replace(' ', '', $pcode)); $area = $district = ''; $sector = substr($pcode,-3, 1); $unit = substr($pcode, -2); $l = strlen($pcode); $first = str_split(substr($pcode, 0, $l-3)); foreach ($first as $c) { if (ctype_digit($c)) { $district .= $c; } else { $area .= $c; } } $res = $db->prepare("SELECT price FROM postcode WHERE area = ? AND district = ? AND ? between sector_min AND sector_max AND ? BETWEEN unit_min AND unit_max AND deliverable "); $res->execute( [ $area, $district, $sector, $unit ] ); $p = $res->fetchColumn(); $price = $p ? number_format($p, 2) : 'N/A'; return [$area, $district, $sector, $unit, $price ]; } RESULTS: EH1 2DB : 1.50 EH1 5BG : 1.80 EH1 5BA : 1.80 EH1 5DG : N/A EH2 7HJ : 2.25 EH3 2PT : 2.50 EH3 8SX : N/A EH14 6DE : N/A
    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.