-
Posts
24,425 -
Joined
-
Last visited
-
Days Won
806
Posts posted by Barand
-
-
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 )
-
4 minutes ago, Nigel12 said:
I then uploaded there score to the database
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" }
-
1 minute ago, SaranacLake said:
Why does formatting get messed up with PHPFreaks [ code ] tags?
Use spaces, not tabs. If your IDE has the option to convert tabs to spaces, use it.
-
32 minutes ago, SaranacLake said:
my array only goes up to 128 items (0-127).
Must be something you are doing. Post code for the benefit of the clairvoyantly challenged.
- 1
-
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!
- 1
-
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 | +---------------+
- 1
-
39 minutes ago, SaranacLake said:
as data entry in phpMyAdmin is a PITA!
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>
- 1
- 1
-
1 hour ago, SaranacLake said:
Not sure how that function would help.
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;
- 1
-
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>
- 1
-
If you have a file that is included in every script (such as db connection stuff) put in there
-
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.
- 1
-
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
-
Same thing as what you are currently doing. Both will use the default timezone setting on the php server to give the time value.
Your local time is currently UTC -6:00 (ie Central time, 3 weeks ago it was UTC -5:00 when DST applied)
What is it on your server?
Does your MySQL server have the same timezone setting?
-
1 hour ago, ajetrumpet said:
date("H:i:s", strtotime("+19 hours"));
Why +19 hours?
-
How strange. Google found 38,600,000 results when tried. Eight download locations on first page.
What were you googling for?
-
Just now, ajetrumpet said:
is ur age showing a bit in that last post Barand?
Only if it means I am of a generation that is willing to try things out and learn by experimenting, research and trial and error (lots of error).
I didn't know the answer off the top of my head so I would have had to try it then relay the results of my trial to you. Or you could just as easily try it.
-
I have built apps for clients that use it and used it when testing. I don't send that many emails myself to know if there is a problem. Whether or not it gets thrown into the spam bucket is down to algorithms on the server rather than the software sending the mail. PHPMailer just makes things a lot easier, especially if you want to send attachments etc. (Every notification email that PHPFreaks sends to me ends up in in my spam even though Freaks domain is in my contacts and I have specified "never block sender". For some reason they must look spammy.)
-
Whenever I have a question like that I try it and see.
-
A DNS lookup converts the domain name you enter into your browser into an ip address.
A reverse lookup does it the opposite way round (IP ==> domain name)
-
6 minutes ago, ajetrumpet said:
I have not read anything on what can be put in the header argument to try and prevent the spamming out.
If there were such a thing, every spammer would be using it.
- 1
Limit to PHP array?
in PHP Coding Help
Posted
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.