-
Posts
24,551 -
Joined
-
Last visited
-
Days Won
821
Community Answers
-
Barand's post in PHP Category Path / Breakcrumb Generator was marked as the answer
After calling your recursive array you need finish up with a single array - you output a separate array during each iteration.
Don't connect to db inside functions - it's the slowest part of the process and inefficient (plus you can quickly reach your connctions limit). Connect once then pass the connection to the functions.
Don't include the separator in you results - add that when you implode (join).
(Sorry for any delay - it's not easy to load an image of data into a database test table)
My method...
function retrieve_category_path($pdo, $id, &$cpa){ // DB connection // Company ID $stmt = $pdo->prepare("SELECT CONCAT(name, '::', position) as name , parent FROM category WHERE id = ? "); $stmt->execute([$id]); while($row=$stmt->fetch()){ $parent =$row['parent']; $name = $row['name']; $cpa[] = $row['name']; // append into array if($row['parent'] > 0){ retrieve_category_path($pdo, $row['parent'], $cpa); } } } $category_path_array = []; retrieve_category_path($pdo, 552, $category_path_array); $breadcrumbs = join('/', array_reverse($category_path_array)); echo $breadcrumbs; // Cars::2/Sports cars::1/Petrol::1/2 Door::0
-
Barand's post in Booking Calendar - PHP MYSQL was marked as the answer
I suggest output like this below. I have used yiur two resources and ny booking data looke like this...
mysql> select * from booking; +----+-------------+---------------------+---------------------+ | id | resource_id | book_start | book_end | +----+-------------+---------------------+---------------------+ | 1 | 1 | 2024-05-13 09:00:00 | 2024-05-13 12:00:00 | | 2 | 1 | 2024-05-15 09:00:00 | 2024-05-15 19:00:00 | | 4 | 1 | 2024-05-16 12:00:00 | 2024-05-16 18:00:00 | | 5 | 2 | 2024-05-13 12:00:00 | 2024-05-17 18:00:00 | +----+-------------+---------------------+---------------------+ The output looks lke this for the 2 resources...
CODE
<?php require 'db_inc.php'; // $pdo = mdbConnect('db1'); // USE YOUR OWN CONNECTION CODE $wkcomm = $_GET['wkcomm'] ?? date('Y-m-d'); $resid = $_GET['resid'] ?? ''; ################################################################################ ## COLUMN HEADINGS ################################################################################ $d1 = new DateTime($wkcomm); $di = new DateInterval('P1D'); $dp = new DatePeriod($d1, $di, 6); $theads = "<tr class='w3-dark-gray'><th>Time Slot</th>"; foreach ($dp as $d) { $theads .= "<th>" . $d->format('D M d') . "</th>"; } $theads .= "</tr>\n"; ################################################################################ ## QUERY BOOKINGS AND BUILD ARRAY IN REQUIRED STRUCTURE FOR OUTPUT ################################################################################ $res = $pdo->prepare("-- -- create temporary table containing the dates of the selected week -- WITH RECURSIVE dateslot (n, slotdate) AS ( SELECT 1, ? UNION ALL SELECT n+1 , date_add(slotdate, INTERVAL 1 DAY) FROM dateslot WHERE n < 7 ), -- -- create temporary table containing the daily 30-minute timeslots -- timeslot (n, starttime, endtime) AS ( SELECT 1, '07:00:00', '07:30:00' UNION ALL SELECT n+1 , addtime(starttime, '00:30:00') , addtime(endtime, '00:30:00') FROM timeslot WHERE n < 24 ) SELECT slotdate , time_format(starttime, '%H:%i') as time , b.id -- -- cross join the two temporary tables to give rows for every timeslot for the seven days -- then match these against the bookings to see which slots fall withing the booking range -- for the selected resource -- FROM dateslot d CROSS JOIN timeslot t LEFT JOIN booking b ON CONCAT(d.slotdate, ' ', t.starttime) < b.book_end AND CONCAT(d.slotdate, ' ', t.endtime) > b.book_start AND b.resource_id = ? ORDER BY starttime, slotdate "); $res->execute([ $wkcomm, $resid ]); $data = []; foreach ($res as $r) { $data[$r['time']][$r['slotdate']] = $r['id']; } ################################################################################ ## LOOP THROUGH ARRAY TO CREATE HTML ROWS ################################################################################ $tdata = ''; foreach ($data as $tslot => $slotdata) { $tdata .= "<tr><td class='w3-gray w3-text-white'>$tslot</td>"; foreach ($slotdata as $booked) { $class = $booked ? 'w3-red' : ''; $tdata .= "<td class='$class'> </td>"; } $tdata .= "</tr>\n"; } ################################################################################ ## FUNCTIONS ################################################################################ function resourceOptions($pdo, $current) { $res = $pdo->query("SELECT id, description FROM resource ORDER BY description "); $opts = "<option value=''>- select resource -</option>\n"; foreach ($res as $r) { $sel = $r['id']==$current ? 'selected' : ''; $opts .= "<option $sel value='{$r['id']}'>{$r['description']}</option>\n"; } return $opts; } ?> <!DOCTYPE html> <html lang='en'> <head> <meta charset="utf-8"> <title>Example</title> <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> <style type='text/css'> table { border-collapse: collapse; width: 100%; } th, td { padding: 4px; } th { border: 1px solid white; } </style> </head> <body> <header class='w3-indigo w3-padding'> <h1>Resource Bookings</h1> </header> <form class='w3-light-gray w3-padding w3-margin-bottom'> Week commencing: <input type='date' name='wkcomm' value='<?=$wkcomm?>'>   Resource: <select name='resid'> <?=resourceOptions($pdo, $resid)?> </select> <button class='w3-blue w3-button'>Refresh</button> </form> <div class='w3-content'> <table class='w3-small' border='1'> <?=$theads?> <?=$tdata?> </table> </div> </body> </html>
-
Barand's post in Text input to replace $description was marked as the answer
Is this closer?
<input id='mytext' type='text'> <button id='btn'>Create output</button> <br><br> <textarea id='target' cols='80' rows='5'></textarea> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> <script type='text/javascript'> $("#btn").click(function() { let txt = $("#mytext").val() let para = `<p style="background: black; padding: 15px; color:white;">${txt}</p>` $("#target").text(para) }) </script>
-
Barand's post in Using preg match to find specific cluster of files was marked as the answer
You must be using an outdated version of php. Str_starts_with() requires version 8.
Use this instead
$required = array_filter($files, fn($v)=>substr($v, 0, 5) == 'alg00');
-
Barand's post in Using ternary operator was marked as the answer
$radint = mt_rand(1,33); $flip = mt_rand(1,2); $radint *= ($flip == 2) ? -1 : 1;
-
Barand's post in Maria DB JSON field insert/update was marked as the answer
Took a fair bit of experimenting to get the right incantations for the update, but...
Data
SELECT * FROM json_test; +----+-------------------------------------------------------------------------------------------------------------------------------+ | id | jstuff | +----+-------------------------------------------------------------------------------------------------------------------------------+ | 1 | {"card": {"4": {"cardName": "This is a card", "iconSelection": "1", "linkLocation": "5", "paragraph": "This is para"}}} | +----+-------------------------------------------------------------------------------------------------------------------------------+ Update
UPDATE json_test SET jstuff = JSON_SET(jstuff, '$."card".4."cardName"', 'This is a different card') WHERE id = 1; Check
SELECT * FROM json_test; +----+-----------------------------------------------------------------------------------------------------------------------------------+ | id | jstuff | +----+-----------------------------------------------------------------------------------------------------------------------------------+ | 1 | {"card": {"4": {"cardName": "This is a different card", "iconSelection": "1", "linkLocation": "5", "paragraph": "This is para"}}} | +----+-----------------------------------------------------------------------------------------------------------------------------------+
-
Barand's post in How to output array instead of a 'loop' echo return from a function? was marked as the answer
You've done the hard work already. Instead of calculating the product, store the selected array.
<?php $primes = array(2, 3, 5, 7, 11, 13, 17, 19, 23); $combos = []; function getAllCombinations($arr, $n, &$combos, $selected = array(), $startIndex = 0) { if ($n == 0) { $combos[] = $selected; // $product = 1; // foreach ($selected as $prime) { // $pr[] = $prime; // $product *= $prime; // $pr[] = $prime; // } // echo "Product: $product\n"; return; } for ($i = $startIndex; $i < count($arr); $i++) { $selected[] = $arr[$i]; getAllCombinations($arr, $n - 1, $combos, $selected, $i + 1); array_pop($selected); // Backtrack and remove the element for next iteration } } getAllCombinations($primes, 4, $combos); echo '<pre>'; foreach ($combos as $com) { printf("%-35s = %5d<br>", join(' × ', $com), array_product($com)); // output numbers and product } ?> giving
2 × 3 × 5 × 7 = 210 2 × 3 × 5 × 11 = 330 2 × 3 × 5 × 13 = 390 2 × 3 × 5 × 17 = 510 2 × 3 × 5 × 19 = 570 2 × 3 × 5 × 23 = 690 2 × 3 × 7 × 11 = 462 2 × 3 × 7 × 13 = 546 2 × 3 × 7 × 17 = 714 2 × 3 × 7 × 19 = 798 2 × 3 × 7 × 23 = 966 2 × 3 × 11 × 13 = 858 2 × 3 × 11 × 17 = 1122 2 × 3 × 11 × 19 = 1254 2 × 3 × 11 × 23 = 1518 2 × 3 × 13 × 17 = 1326 2 × 3 × 13 × 19 = 1482 2 × 3 × 13 × 23 = 1794 2 × 3 × 17 × 19 = 1938 2 × 3 × 17 × 23 = 2346 2 × 3 × 19 × 23 = 2622 2 × 5 × 7 × 11 = 770 2 × 5 × 7 × 13 = 910 . . 5 × 17 × 19 × 23 = 37145 7 × 11 × 13 × 17 = 17017 7 × 11 × 13 × 19 = 19019 7 × 11 × 13 × 23 = 23023 7 × 11 × 17 × 19 = 24871 7 × 11 × 17 × 23 = 30107 7 × 11 × 19 × 23 = 33649 7 × 13 × 17 × 19 = 29393 7 × 13 × 17 × 23 = 35581 7 × 13 × 19 × 23 = 39767 7 × 17 × 19 × 23 = 52003 11 × 13 × 17 × 19 = 46189 11 × 13 × 17 × 23 = 55913 11 × 13 × 19 × 23 = 62491 11 × 17 × 19 × 23 = 81719 13 × 17 × 19 × 23 = 96577
-
Barand's post in Using explode but only last string value being added to array was marked as the answer
You may echo all of them but, each time through the loop, $tld is overwritten - you are just left with last one.
-
Barand's post in How do I compare two rows in a SQL query? was marked as the answer
You should first learn the basic concepts, such as the difference between column names and column values and other attributes
-
Barand's post in Success page for cinema ticket booking system was marked as the answer
I am assuming that this is an AJAX/Fetch process as you reference javscript in your initial post. Is it?
-
Barand's post in Create folder in file structure from php application was marked as the answer
See https://www.php.net/mkdir
-
Barand's post in Creating array to POST with jQuery was marked as the answer
Yes.
That is what I was going to suggest if you didn't want to use the hidden field approach. That way you send just a single querystring which will be handled automatically to create the $_POST array
Perhaps
$stmt = $pdo->prepare("INSERT INTO mytable (zoneType, zoneName, printValue) VALUES (?,?,?)"); foreach ($_POST['zoneName'] as $k => $zn) { if ($zn) { $stmt->execute([ $_POST['zoneType'][$k], $zn, $_POST['printValue'][$k] ]); } }
-
Barand's post in Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number was marked as the answer
I wouldn't waste time on the first SELECT query.
Place a UNIQUE key constraint on the email column then
function createNewUser($pdo, $fname, $lname, $email, $password) { try { $sql2 = "INSERT INTO user (fname, lname, email, password) VALUES (:fname, :lname, :email, :password)"; $hashedPwd = password_hash($password, PASSWORD_BCRYPT); $stmt = $pdo->prepare($sql2); $stmt->execute([ ':fname' => $fname, ':lname' => $lname, ':email' => $email, ':password' => $hashedPwd ]); return 'User Created'; } catch (PDOException $e) { if ( str_contains($e->getMessage(), '1062 Duplicate entry')) { return "That email already exists"; } else throw $e; } }
-
Barand's post in Function per field or select all data was marked as the answer
Whichever approach you use, do NOT connect to the database inside every function. Connect once to the db at start of each script and pass the connection to the functions. (The connection is the slowest part of the process)
So the function calls are
getFirstName($pdo, $id)
getLastName($pdo, $id)
getEmail($pdo, $id)
getDietary($pdo, $id)
getX($pdo, $id)
I'd go with a single function
$user = getUserData($pdo, $user_id); // get an array containing the user data if ($user) { $fullname = $user['firstname'] . ' ' . $user['lastname']; // use array elements as required } function getUserData($pdo, $id) { $res = $pdo->prepare("SELECT firstname , lastname , email , diet , gender , x , y , z FROM user WHERE id = ? "); $res->execute([$id]); return $res->fetch(); }
-
Barand's post in PHP Date Sort using scandir() was marked as the answer
I don't fancy the chances of sorting your files by the dates embedded in their names.
Instead, get the filenames, get the date of each file, store in array, then sort the dates.
$files = glob("$dir/*.*"); $fdates = []; foreach ($files as $f) { $fdates[basename($f)] = date('Y-m-d',filemtime($f)); } asort($fdates); echo '<ul>'; foreach ($fdates as $fn => $dt) { echo "<li>$dt – $fn</li>"; } echo "</ul>"; Results wil look something like this
-
Barand's post in finding out the % of 2 variables was marked as the answer
current ------- X 100 = percent full
-
Barand's post in Associating cinema times with Screen numbers was marked as the answer
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>
-
Barand's post in Counting based on IF statement issue was marked as the answer
This query should do it
SELECT SUM(visited IS NULL AND timestampdiff(MONTH, created_at, now()) >= 15) as expired , SUM(visited IS NULL AND timestampdiff(MONTH, created_at, now()) < 3) as pending , SUM(visited IS NOT NULL) as ok FROM users;
-
Barand's post in Timestamp difference - using subtraction between the two in the database was marked as the answer
The mysql function NOW() gives the current datetime.
mysql> SELECT timestampdiff(DAY, '2024-01-28 09:41:36', NOW() ) as diff; +------+ | diff | +------+ | 1 | +------+
-
Barand's post in Php mysql random link generate for a prize win was marked as the answer
I had in mind something like this...
CREATE TABLE `win_log` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, `won` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `collected` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_win_log_user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; Bob (user_id #123) wins on Saturday. He also wins on Sunday.
Each time he wins, you record the win with this query (inserting $_SESSION['user_id'] into the table)
INSERT INTO win_log (user_id) VALUES (?); So now you have
TABLE: win_log +----+---------+---------------------+-----------+ | id | user_id | won | collected | +----+---------+---------------------+-----------+ | 1 | 123 | 2024-01-20 18:53:21 | NULL | | 2 | 123 | 2024-01-21 10:33:45 | NULL | +----+---------+---------------------+-----------+ On Monday he goes to collect his tokens. You check he is allowed to by...
SELECT COUNT(*) as tot FROM win_log WHERE user_id = ? AND collected IS NULL; If the returned count is > 0 he can go ahead and collect.
You record the collection with...
UPDATE win_log SET collected = NOW() WHERE user_id = ? AND collected IS NULL ORDER BY won LIMIT 1; You now have
+----+---------+---------------------+---------------------+ | id | user_id | won | collected | +----+---------+---------------------+---------------------+ | 1 | 123 | 2024-01-20 18:53:21 | 2024-01-22 19:01:25 | | 2 | 123 | 2024-01-21 10:33:45 | NULL | +----+---------+---------------------+---------------------+
-
Barand's post in JavaScript Calculation Challenge: Updating Sub-Total and Total Less Amount Dynamically in a Table was marked as the answer
Use the javascript debugger to step through the code to see if it's doing what you expect and that the variables contain what you expect.
-
Barand's post in MATCH AGAINST using my 'Terms' table and with 'Links' was marked as the answer
You need to join the two tables on the link_id so you match the terms to their parent link
Do you have a specific reason for using a fulltext search? Would a simpler "LIKE" suffice. For example
SELECT l.id as linkID , l.url , t.term FROM links l JOIN terms t ON l.id = t.link_id WHERE t.term LIKE '%ine%' OR l.url LIKE '%ine%'; linkID | url | term ----------+----------------+----------------- 2 | page2.php | zine 2 | page2.php | magazine 2 | page2.php | online -
Barand's post in Remove duplicate words was marked as the answer
PS
I am in complete agreement with @kicken - you need to restructure your tables
+---------------+ | link | +---------------+ | id (PK) |-----+ | url | | +---------------+ +---------------+ | | term | | +---------------+ | | id (PK) | +-----<| link_id (FK) | | term | +---------------+ So that your data looks like this... TABLE: link TABLE: term +-----+-------------------+ +-----+---------+---------------------+ | id | url | | id | link_id | term | +-----+-------------------+ +-----+---------+---------------------+ | 1 | page1.php | | 1 | 1 | Zeitgeist | | 2 | page2.php | | 2 | 1 | conspiracy theories | +-----+-------------------+ | 3 | 1 | 9/11 | | 4 | 1 | 9 11 | | 5 | 2 | zine | | 6 | 2 | magazine | | 7 | 2 | online | | 8 | 2 | newspaper | | 9 | 2 | press | | 10 | 2 | alternative | | 11 | 2 | coldtype | | 12 | 2 | world news | +-----+---------+---------------------+ Then all you need is a couple of simple queries. (My reply to your previous topic assumed were using a correctly normalized design as above)
-
Barand's post in Test a value from a PHP was marked as the answer
That line always assigns the value "1" to $bob. When testing values for equality you need "==", therefore it should be
if ($bob == 1)
-
Barand's post in Dynamic Student Selection: Populating Student Names Based on Class and Arms in a Non-Editable Session/Term Environment was marked as the answer
Sorry, missed the bit about the second select being year and not class. Try
SELECT s.id , s.firstname , s.lastname , c.classname FROM class c JOIN student_class sc ON sc.classid = c.id AND semesterid = ? JOIN student s ON sc.studentid = s.id WHERE c.year = ? ORDER BY lastname;