-
Posts
24,608 -
Joined
-
Last visited
-
Days Won
831
Everything posted by Barand
-
Store the current position, n, and the array as session variables and pass the n-1 or n+1 in your hyperlinks
-
Some complex maths is required. The array has an index, so if you are currently on the Nth element, subtract 1 to get the previous item or add 1 to get the next $current = $files[$n]; $previous = $files[$n-1]; $next = $files[$n+1];
-
getting data via OSM Overpass API with XPath & PHP-SimpleXML
Barand replied to dil_bert's topic in PHP Coding Help
OK, we won't. Bye!- 1 reply
-
- 1
-
-
(HELP) PHP to get random line from text file for video embed
Barand replied to Matt1972's topic in PHP Coding Help
Stop blindly copying and pasting. Apply a little thought to what the code is doing. You'll learn more that way. function random_title () { $titles = file (“titles.txt”, FILE_IGNORE_NEW_LINES); $random_title = $titles[array_rand($titles)]; return ucwords($random_title); } -
(HELP) PHP to get random line from text file for video embed
Barand replied to Matt1972's topic in PHP Coding Help
It isn't a sound method. Suppose you have 3 titles. intval(count($titles)/3) = 1, so you now get a random integer between 0 and 1 which you multiply by 3. Therefore $num will be 0 or 3. The titles are indexed 0, 1 and 2. IE index 3 doesn't exist. See the problem? Use array_rand() $random_title = $titles[array_rand($titles)]; -
(HELP) PHP to get random line from text file for video embed
Barand replied to Matt1972's topic in PHP Coding Help
Perhaps you could explain the rationale behind this method for getting the title... $num = rand (0, intval (count ($titles) / 3)) * 3 -
-
Christmas has come early! <?php const IMGDIR = 'images/'; const THUMBDIR = 'thumbs/'; const THUMBSIZE = 150; // max thumbnail dimension const NUM = 100; // number of images to be processed on each run $images = glob(IMGDIR.'{*.png,*.jpg}', GLOB_BRACE); $thumbs = glob(THUMBDIR.'{*.png,*.jpg}', GLOB_BRACE); // reduce to basenames only $images = array_map('basename', $images); $thumbs = array_map('basename', $thumbs); // copy the next NUM images to $todo list where thumbnails do not yet exist $todo = array_slice(array_diff($images, $thumbs), 0, NUM); $output = ''; foreach ($todo as $fn) { $sz = getimagesize(IMGDIR.$fn); if ($sz[0] == 0) continue; // not an image $ok = 0; $out = null; switch ($sz['mime']) { // check the mime types case 'image/jpeg': $im = imagecreatefromjpeg(IMGDIR.$fn); $ok = $im; $out = 'imagejpeg'; break; case 'image/png': $im = imagecreatefrompng(IMGDIR.$fn); $ok = $im; $out = 'imagepng'; break; default: $ok = 0; } if (!$ok) continue; // not png or jpg // calculate thumbnail dimensions if ($sz[0] >= $sz[1]) { // landscape $w = THUMBSIZE; $h = THUMBSIZE * $sz[1]/$sz[0]; } else { // portrait $h = THUMBSIZE; $w = THUMBSIZE * $sz[0]/$sz[1]; } // copy and resize the image $tim = imagecreatetruecolor(THUMBSIZE, THUMBSIZE); $bg = imagecolorallocatealpha($tim,0xFF,0xFF,0xFF,127); imagefill($tim, 0, 0, $bg); imagecolortransparent($tim, $bg); // centre the image in the 150 pixel square $dx = (THUMBSIZE - $w) / 2; $dy = (THUMBSIZE - $h) / 2; imagecopyresized($tim, $im, $dx, $dy, 0, 0, $w, $h, $sz[0], $sz[1]); imagesavealpha($tim, true); $out($tim, THUMBDIR.$fn); imagedestroy($im); imagedestroy($tim); $output .= "<img src='".THUMBDIR."$fn' alt='$fn'>\n"; } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="content-language" content="en"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Create Thumbnails</title> <meta name="author" content="Barry Andrew"> <meta name="creation-date" content="10/09/2019"> <style type="text/css"> body { font-family: verdana, sans-serif; font-size: 11pt; } header { background-color: black; color: white; padding: 15px 10px;} img { margin: 5px; } </style> </head> <body> <header> <h1>New Thumbnail Images</h1> </header> <?=$output?> </body> </html>
-
If you want to show a gallery then, yes, you really want thumbnail size images to display. You can have an image that is originally 4000 pixels x 2500 pixels and shrink it in the html image tag by specifying width='200' height = '125' so it looks like a thumbnail but you are still transferring the multi MB file. You therefore need to run a job to create thumbnail versions of all your images. (The best time to create them is when the image is uploaded but too late for that now). Perhaps have an images folder with the original images and a thumbs folder to contain the thumbnail images, one for each original) When you create the thumb images, decide on the size of square into which they should fit (say 150 or 200 pixels). Then calculate the thumbsize so the longest dimension just fits that square (be it landscape or portrait) then calculate what the shorter dimension needs to be to maintain the same aspect ratio. Then you just copy/resize the image to the new file.
-
I also can't understand why your array index values are limited to a single signed byte. I'd expect a maximum of at least 2 billion (memory permitting) Array ( [2147483647] => 1 ) or even this on a 64 bit system Array ( [9223372036854775807] => 1 )
-
Don't store totals in a database, store the individual records that make up that total. That way you have an audit trail. With the responses, you can get info on which questions a user got right or wrong, which is lot more useful that just knowing how many. When you want the scores, just count the correct responses.
-
Running your readdir() code on one of my folders, with 528 files, loads all of them into the array. Last bit of my var_dump... [524]=> string(9) "xmlns.php" [525]=> string(15) "xmltestdata.xml" [526]=> string(11) "YMDdiff.php" [527]=> string(10) "zodiac.txt" }
-
Use spaces, not tabs. If your IDE has the option to convert tabs to spaces, use it.
-
Must be something you are doing. Post code for the benefit of the clairvoyantly challenged.
-
You could've had a database set up in less time than you spent moaning about what a PITA it is. It takes about half a dozen statements to create an image table from your image directory. JFDI. const IMGDIR = 'images/'; $db->exec("CREATE TABLE IF NOT EXISTS `image_lib` ( `img_id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) DEFAULT NULL, `path` varchar(255) DEFAULT NULL, `width` int(11) DEFAULT NULL, `height` int(11) DEFAULT NULL, `mime_type` varchar(20) DEFAULT NULL, `description` varchar(255) DEFAULT NULL, `img_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`img_id`), FULLTEXT KEY `idx_image_lib_description` (`description`) ) "); $ins = $db->prepare("INSERT INTO image_lib (name, path, width, height, mime_type) VALUES (?,?,?,?,?)") ; $imgs = glob(IMGDIR.'{*.png,*.jpg}', GLOB_BRACE); foreach ($imgs as $i) { $s = getimagesize($i); $ins->execute( [ basename($i), IMGDIR, $s[0], $s[1], $s['mime'] ]); } Job done!
-
Are you not storing the users' answers anywhere? Write a record to the "user_response" table when a user answers a question. Then you have a record of which questions each user has answered. Only select questions for a user where there is no record in the response table for that question. SELECT Question , Answer1 , Answer2 , Answer3 , CorrectAnswer FROM question q LEFT JOIN user_response r ON q.id = r.q_id WHERE r.q_id IS NULL ORDER BY RAND() LIMIT 1 +-----------+ +-----------+ | user | | question | +-----------+ +-----------+ | user_id |--+ +----| id | | name | | | | question | +-----------+ | | | etc | | | +-----------+ | | | +---------------+ | | | user_response | | | +---------------+ | | | q_id |>-+ +--<| user_id | | test_date | | answer | +---------------+
-
Anything with phpMyAdmin is a PITA. There are alternatives MySQL Workbench Write a php script for your data entry. (You can create the initial db table by scanning the directory then you just need to add the descriptions. You can then easily give the users a facility to search the image descriptions for keywords)
-
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 = ' · · · '; $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') . "  "; if ($kPages==1) { return $out; } $out .= ($page > 1) ? "<div class='pagipage' data-pn='$p'>Prev</div> " : "<div class='pagipage x' data-pn='$p' disabled>Prev</div> "; 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 ? " <div class='pagipage' data-pn='$n'>Next</div>" : " <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> </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>
-
The link that @chhorn gave you has an example that shows exactly how it would help. All you had to do was click it and read.
-
Nothing to do with version of PHP. The problem is with variable scope. You need to pass the variable to the function, same as you have with $ip. foreach($ranges as $key => $value){ if($key<=$code){ if($ranges[$key][0]>=$code){$two_letter_country_code=$ranges[$key][1];break;} } } On closer reading, the variable is defined in the loop, but only if the two conditions are true. Otherwise it is undefined. Define it as $two_letter_country_code = ''; before the foreach loop;
-
If you look up GROUP_CONCAT in the MySQL manual... The result is truncated to the maximum length that is given by the group_concat_max_len system variable, which has a default value of 1024. The value can be set higher, although the effective maximum length of the return value is constrained by the value of max_allowed_packet. The syntax to change the value of group_concat_max_len at runtime is as follows, where val is an unsigned integer: SET [GLOBAL | SESSION] group_concat_max_len = val;
-
Or you could take the view that the product is a timeslot. If they want part of one and part of the next then they buy both. Check which slots contain or over lap the required times as this example does (see line 40) ... <?php $business_hours = [ 1 => [ 'am_from' => '10:00', 'am_to' => '12:00', 'pm_from' => '13:00', 'pm_to' => '19:00' ], 2 => [ 'am_from' => '08:00', 'am_to' => '12:00', 'pm_from' => '13:00', 'pm_to' => '17:00' ], 3 => [ 'am_from' => '12:00', 'am_to' => '12:00', 'pm_from' => '13:00', 'pm_to' => '19:00' ], 4 => [ 'am_from' => '08:00', 'am_to' => '12:00', 'pm_from' => '13:00', 'pm_to' => '17:00' ], 5 => [ 'am_from' => '08:00', 'am_to' => '12:00', 'pm_from' => '13:00', 'pm_to' => '13:00' ], ]; //------------------------------------------------------------ // from above array, generate daily 30 minute slots // for the next 15 days // $slots = []; $dt1 = new DateTime(); $intwd = DateInterval::createFromDateString('next weekday'); $dp_days = new DatePeriod($dt1, $intwd, 14); foreach ($dp_days as $d) { $dno = $d->format('w'); $times = $business_hours[$dno]; $slots[$d->format('Y-m-d')] = generateSlots($times); } //------------------------------------------------------------ // place these bookings in their slots // $bookings = [ ['title' => 'Test 1', 'start' => '2019-11-26 10:15', 'end' => '2019-11-26 11:30'], ['title' => 'Test 2', 'start' => '2019-11-29 11:00', 'end' => '2019-11-29 12:00'], ['title' => 'Test 3', 'start' => '2019-12-02 15:30', 'end' => '2019-12-02 16:30'] ]; foreach ($bookings as $b) { $sd = new DateTime($b['start']); $ed = new DateTime($b['end']); $date = $sd->format('Y-m-d'); $st = $sd->format('H:i'); $et = $ed->format('H:i'); foreach ($slots[$date] as &$s) { if ($s['t'] != '') continue; // not available if ($et > $s['s'] && $st < $s['e']) { // if booking is in or overlaps slot ( LINE 40 ) $s['t'] = $b['title']; // place title into slot } } } //------------------------------------------------------------ // output the slots to the page // $tdata = ''; foreach ($slots as $d => $ddata) { if ((new DateTime($d))->format('w')==1) { $tdata .= "<tr><td colspan='12'> </td></tr>\n"; } $tdata .= "<tr><td>" . date('D d M', strtotime($d)) . '</td>'; foreach ($ddata as $slt) { switch ($slt['t']) { case 'closed': $cls = 'class="closed"'; $txt = ''; break; case '': $cls = ''; $txt = ''; break; default: $cls = 'class="booked"'; $txt = $slt['t']; } $tdata .= "<td $cls>$txt</td>"; } $tdata .= "</tr>\n"; } /** * generate daily timeslots * * @param array $times - array of business hours for the day */ function generateSlots($times) { $stime = ''; $dt1 = new DateTime('08:00:00'); $dt2 = new DateTime('19:00:00'); $di = new DateInterval('PT1H'); $dp = new DatePeriod($dt1, $di, $dt2); $slots = []; foreach ($dp as $t) { $k = $t->format('G'); $h1 = $t->format('H:i'); $h2 = $t->modify('+1 hour')->format('H:i'); $text = ($h1 >= $times['am_from']) && ($h1 < $times['am_to']) || ($h1 >= $times['pm_from']) && ($h1 < $times['pm_to']) ? '' : 'closed' ; $slots[$k] = [ 's'=>$h1, 'e'=>$h2, 't'=>$text]; } return $slots; } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Example Bookings</title> <style type="text/css"> body, table { font-family: calibri, sans-serif; font-size: 11pt; } table { border-collapse: collapse; width: 90%; margin: 0 auto; } th { padding: 4px 2px; background-color: #006EFC; color: #FFF; border-color: #FFF;} td { background-color: #FFF; padding: 2px; } td.closed { background-color: #888; color: #FFF; } td.booked { background-color: #FFC0C0; } </style> </head> <body> <header> <h1>Example Bookings</h1> </header> <table border='1'> <tr><th rowspan='2'>Date</th><th colspan='4'>AM</th><th></th><th colspan='6'>PM</th></tr> <tr><th>8 – 9</th><th>9 – 10</th><th>10 – 11</th><th>11 – 12</th> <th>12 – 1</th><th>1 – 2</th><th>2 – 3</th><th>3 – 4</th><th>4 – 5</th><th>5 – 6</th><th>6 – 7</th></tr> <?=$tdata?> </table> </body> </html>
-
strtotime() returning many different times based on type of visitor
Barand replied to ajetrumpet's topic in PHP Coding Help
If you have a file that is included in every script (such as db connection stuff) put in there -
strtotime() returning many different times based on type of visitor
Barand replied to ajetrumpet's topic in PHP Coding Help
Having run the above code, my phpinfo() in the same script shows However, the output from a second identical script was exactly the same - the default reverted to London time. So the "data.timezone" setting is the one used unless it is set in the script. Running phpinfo() in a separate script shows "London" for both. So, Yes. You would need it every script unless you set it at ini file level. -
strtotime() returning many different times based on type of visitor
Barand replied to ajetrumpet's topic in PHP Coding Help
You can override the ini setting by setting it in your code prior to using any date/time functions echo 'Default : ' . date('H:i:s') . '<br>'; // 12:43:34 date_default_timezone_set('America/Chicago'); echo 'Central : ' . date('H:i:s') . '<br>'; // 06:43:34