Jump to content

Barand

Moderators
  • Posts

    24,450
  • Joined

  • Last visited

  • Days Won

    809

Community Answers

  1. Barand's post in hoto make prepared statement was marked as the answer   
    Not allowed. Only values can be passed as parameters, not table or column identifiers.
    Having variable table names is oftenindicative of a poor database design.
    Don't insert primary keys (Ans_id) in INSERT statements, let them be created automatically.
    $stmt = $pdo->prepare("INSERT INTO tablename (answer, answer_image) VALUES (?, ?)"); $stmt->execute( [ $answer, $image_path ] );  
  2. Barand's post in New to PHP Don't understand this syntax error. Please Help. was marked as the answer   
    When it encounters the "<p>" it is still in the php section of the code and the "<p>" isn't valid php code.
    You need to exit from php before you enter the html. Move the "?>" line ...

  3. Barand's post in Removing / editing certain keywords from array content was marked as the answer   
    One way is to find the positions of the "]" and and the "(" and grab the text between those points.
    $qa = [ "[Question - Geography Chapter2] How would you describe humans' relationship with the physical environment? (Page 42)", "[Question - Geography Chapter4] What is a natural resource? (Page 67)", "[Question - Geography Chapter3] What are two or three resources which you cannot do without? What are the reasons for your choices? (Page 52)" ]; foreach ($qa as $k => &$q) { $p1 = strpos($q, ']'); $p2 = strpos($q, '('); $q = trim(substr($q, $p1+1, $p2-$p1-1)); }  
  4. Barand's post in how to append data to end of array in php was marked as the answer   
    Not without any psychic abilities.
  5. Barand's post in adding minutes was marked as the answer   
    Example...
    DATA
    mysql> select * from worked_hours; +----+---------+---------------------+---------------------+ | id | user_id | start_time | finish_time | +----+---------+---------------------+---------------------+ | 1 | 1 | 2024-06-17 09:00:00 | 2024-06-17 17:26:00 | | 2 | 1 | 2024-06-18 09:00:00 | 2024-06-18 17:31:00 | | 3 | 1 | 2024-06-19 09:00:00 | 2024-06-19 17:12:00 | | 4 | 1 | 2024-06-20 09:00:00 | 2024-06-20 17:40:00 | | 5 | 1 | 2024-06-21 09:00:00 | 2024-06-21 17:01:00 | | 6 | 1 | 2024-06-22 09:00:00 | 2024-06-22 17:36:00 | | 7 | 1 | 2024-06-23 09:00:00 | 2024-06-23 17:47:00 | | 8 | 1 | 2024-06-24 09:00:00 | 2024-06-24 17:19:00 | | 9 | 2 | 2024-06-17 09:00:00 | 2024-06-17 17:20:00 | | 10 | 2 | 2024-06-18 09:00:00 | 2024-06-18 17:43:00 | | 11 | 2 | 2024-06-19 09:00:00 | 2024-06-19 17:45:00 | | 12 | 2 | 2024-06-20 09:00:00 | 2024-06-20 17:35:00 | | 13 | 2 | 2024-06-21 09:00:00 | 2024-06-21 17:26:00 | | 14 | 2 | 2024-06-22 09:00:00 | 2024-06-22 17:14:00 | | 15 | 2 | 2024-06-23 09:00:00 | 2024-06-23 17:55:00 | | 16 | 2 | 2024-06-24 09:00:00 | 2024-06-24 17:15:00 | | 17 | 3 | 2024-06-17 09:00:00 | 2024-06-17 17:40:00 | | 18 | 3 | 2024-06-18 09:00:00 | 2024-06-18 17:15:00 | | 19 | 3 | 2024-06-19 09:00:00 | 2024-06-19 17:35:00 | | 20 | 3 | 2024-06-20 09:00:00 | 2024-06-20 17:26:00 | | 21 | 3 | 2024-06-21 09:00:00 | 2024-06-21 17:38:00 | | 22 | 3 | 2024-06-22 09:00:00 | 2024-06-22 17:41:00 | | 23 | 3 | 2024-06-23 09:00:00 | 2024-06-23 17:00:00 | | 24 | 3 | 2024-06-24 09:00:00 | 2024-06-24 17:04:00 | +----+---------+---------------------+---------------------+ QUERY
    WITH hrs as ( SELECT user_id , DAYNAME(start_time) as day , TIMESTAMPDIFF(MINUTE, start_time, finish_time)-30 as mins , SUM(TIMESTAMPDIFF(MINUTE, start_time, finish_time)-30) over w1 as cum , SUM(TIMESTAMPDIFF(MINUTE, start_time, finish_time)-30) over w1 - TIMESTAMPDIFF(MINUTE, start_time, finish_time)-30 <= 1500 as include FROM worked_hours WINDOW w1 as (PARTITION BY user_id ORDER BY start_time) ) SELECT user_id , day , mins , cum FROM hrs WHERE include; RESULTS

  6. Barand's post in how to add strings to an associatve array was marked as the answer   
    $data['sub'] = 'math'; $data['level'] = 'valley';  
  7. Barand's post in looping through an array in php was marked as the answer   
    One way...
    <?php $data = array ( 0 => array ( 'Q_id' => '1.1.1|||1.1.2|||1.1.3|||1.1.4|||1.1.5|||1.1.6|||1.1.7|||1.1.8|||1.1.9|||1.1.10|||1.1.11|||1.1.12|||1.1.13|||1.1.14|||1.1.15|||1.1.16|||1.1.17|||1.1.18|||1.1.19|||1.1.20|||1.1.21|||1.1.22|||1.1.23|||1.1.24|||1.1.25|||1.1.26|||1.1.27|||1.1.28|||1.1.29|||1.1.30|||1.1.31|||1.1.32|||1.1.33|||1.1.34|||1.1.35|||1.1.36|||1.1.37|||1.1.38|||1.1.39|||1.1.40|||1.1.41|||1.1.42|||1.1.43|||1.1.44|||1.1.45|||1.1.46|||1.1.47|||1.1.48|||1.1.49|||1.1.50', 'QueNo' => NULL, 'qNo' => '1|||2|||3|||4|||5|||6|||7|||8|||9|||10|||11|||12|||13|||14|||15|||16|||17|||18|||19|||20|||21|||22|||23|||24|||25|||26|||27|||28|||29|||30|||31|||32|||33|||34|||35|||36|||37|||38|||39|||40|||41|||42|||43|||44|||45|||46|||47|||48|||49|||50', 'SECTION' => 'SECTION A', ), 1 => array ( 'Q_id' => '1.1.51|||1.1.51.2|||1.1.51.3|||1.1.51.4|||1.1.51.5|||1.1.51.6|||1.1.51.7|||1.1.51.8|||1.1.51.9|||1.1.51.10', 'QueNo' => 'b|||c|||d|||e|||f|||g|||h|||i|||j', 'qNo' => '51|||51|||51|||51|||51|||51|||51|||51|||51|||51','SECTION' => 'SECTION B', ), ) ; ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Example</title> <style type='text/css'> table { border-collapse: collapse; width: 500px; } td { padding: 8px } </style> </head> <body> <table border='1'> <?php foreach ($data as $k => $v) { foreach ($v as $k1 => $v1) { // do something (such as output) $vals = str_replace('|||', ', ', $v1); echo "<tr><td>$k</td><td>$k1</td><td>$vals</td></tr>"; } } ?> </table> </body> </html>
  8. Barand's post in XML File with tags was marked as the answer   
    Have you triedd using xpath()?
    <?php $str = '<xml><chapter num="17"> <verse num="1">And after six days Jesus taketh Peter, James, and John his brother, and bringeth them up into an high mountain apart,</verse> <verse num="2">And was transfigured before them: and his face did shine as the sun, and his raiment was white as the light.</verse> <verse num="3">And, behold, there appeared unto them Moses and Elias talking with him.</verse> <verse num="4">Then answered Peter, and said unto Jesus, Lord, it is good for us to be here: if thou wilt, let us make here three tabernacles; one for thee, and one for Moses, and one for Elias.</verse> <verse num="5">While he yet spake, behold, a bright cloud overshadowed them: and behold a voice out of the cloud, which said, This is my beloved Son, in whom I am well pleased; hear ye him.</verse> <verse num="6">And when the disciples heard <i>it,</i> they fell on their face, and were sore afraid.</verse> <verse num="7">And Jesus came and touched them, and said, <span class="j">Arise, and be not afraid. </span></verse> <verse num="8">And when they had lifted up their eyes, they saw no man, save Jesus only.</verse> <verse num="9">And as they came down from the mountain, Jesus charged them, saying, <span class="j">Tell the vision to no man, until the Son of man be risen again from the dead. </span></verse> <verse num="10">And his disciples asked him, saying, Why then say the scribes that Elias must first come?</verse> <verse num="11">And Jesus answered and said unto them, <span class="j">Elias truly shall first come, and restore all things. </span></verse> <verse num="12"><span class="j">But I say unto you, That Elias is come already, and they knew him not, but have done unto him whatsoever they listed. Likewise shall also the Son of man suffer of them. </span></verse> <verse num="13">Then the disciples understood that he spake unto them of John the Baptist.</verse> <verse num="14">And when they were come to the multitude, there came to him a <i>certain</i> man, kneeling down to him, and saying,</verse> <verse num="15">Lord, have mercy on my son: for he is lunatick, and sore vexed: for ofttimes he falleth into the fire, and oft into the water.</verse> <verse num="16">And I brought him to thy disciples, and they could not cure him.</verse> <verse num="17">Then Jesus answered and said, <span class="j">O faithless and perverse generation, how long shall I be with you? how long shall I suffer you? bring him hither to me. </span></verse> </chapter></xml> '; $xml = simplexml_load_string($str); $verses = $xml->xpath('//verse'); ?> <!DOCTYPE html> <html lang='en'> <head> <title>XML example</title> <meta charset='utf-8'> <style type='text/css'> .j { color: blue; font-style: italic; font-weight: 600; } </style> </head> <body> <?php foreach ($verses as $v) { echo "<p>{$v->asXML()}</p>"; } ?> </body> </html> Gives...

  9. Barand's post in I want to learn SQL for data analysis(I've understood company's database organization) was marked as the answer   
    There's a beginners' SQL tutorial in my forum signature. It may help.
  10. 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  
  11. 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'>&nbsp;</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?>'> &emsp; 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>  
  12. 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>
  13. 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');  
  14. 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;  
  15. 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"}}} | +----+-----------------------------------------------------------------------------------------------------------------------------------+  
  16. 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(' &times; ', $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  
  17. 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.
  18. 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
  19. 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?
  20. Barand's post in Create folder in file structure from php application was marked as the answer   
    See https://www.php.net/mkdir
  21. 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] ]); } }  
  22. 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; } }  
  23. 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(); }  
  24. 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 &ndash; $fn</li>"; } echo "</ul>"; Results wil look something like this

     
  25. Barand's post in finding out the % of 2 variables was marked as the answer   
    current ------- X 100 = percent full  
×
×
  • 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.