Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 11/08/2019 in all areas

  1. 3 points
    +----------------+ +----------------+ | 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 |<----------+ +----------+
  2. 2 points
    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>
  3. 2 points
    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>
  4. 2 points
    Yes but you don't want to run both at the same time. If you really wanted to, you would need to change the Apache port on one of them as they both use port 80
  5. 2 points
    Hi, This is a probably a wrong way of inserting new email into the DB and can result in race conditions. You should be inserting the new email directly into the DB and your column for ermail ids should be unique so that it throws an exception for duplicate entries.
  6. 1 point
    elseif (is_numeric($minPrice)) probably needs to be elseif (!is_numeric($minPrice)) // error if NOT numeric
  7. 1 point
  8. 1 point
    This tells me you have an actual directory named 2019-holiday-party inside your gallery folder. When I created a similar directory on my end then I get results similar to yours. The problem is mod_dir which in addition to handling DirectoryIndex files, I'm not sure exactly how it's interacting with your mod_rewrite rules, but it appears as though it's triggers based on the original request url instead of the re-written URL. When it issues the redirect however it still picks up the query-string that was added to the re-written URL. This trailing slash behavior can be disabled by setting DirectorySlash Off in your configuration. That should resolve the problem, though I'm not sure it's a good solution. Another solution would be to make sure your pretty URL's don't map to an actual directory on the server.
  9. 1 point
    RewriteCond %{REQUEST_FILENAME} !-d Ensures the request does not map to a valid directory. RewriteCond %{REQUEST_FILENAME} !-f Ensures the request does not map to a valid file RewriteCond %{REQUEST_FILENAME}.php -f Ensures that if you add .php to the requested location, it does map to a valid file. RewriteRule .* $0.php [L] If all the above conditions are true, then this matches the entire URL (the .*) and rewrites it to include the .php suffix. The parentheses create a group which can be referenced in the substitution. In this instance they are not needed because you want to refer to the entire match which is already handled by $0 which is an automatic reference to the matching input string as a whole. If you wanted to match only a subset of the input string, then you'd use parentheses and $1, $2, etc.
  10. 1 point
    On your gallery page, you have a process to get an array of images which you should ensure has a numerically based index (0, 1, 2, ...). First, you need to take that logic and put it in a separate file that you will include() in your gallery page. You need to do this because you will need to include the same logic on the "enlarged version" script so you always get the exact same array. Never "copy/paste" such logic between multiple pages - especially when those multiple pages are dependent upon the data being the same. Then, on your gallery page, make each image a link to open the image in the "enlarged version" page. That link would look something like this showfull.php?id=3 Lastly, your enlarged version page could look something like this. <?php //Include script to generate the image array include('getImageArray.php'); //Get the passed image id $imageId = isset($_GET['id']) ? int($_GET['id']) : 0; //Check if the image exists if(!array_key_exists($imageId, $images) { //Error handling when the selected image does not exist $output = "Unable to retireve image"; } else { //Detemine if there will be a "prev" button (assumed array is always zero-based $prevId = $imageId-1; $prevLink = (array_key_exists($prevId, $images) ? "<a href='showfull.php?id={$prevId}'>PREV</a>" : ''; //Detemine if there will be a "next" button $nextId = $imageId+1; $nextLink = (array_key_exists($nextId, $images) ? "<a href='showfull.php?id={$nextId}'>NEXT</a>" : ''; //Create the output $output = "SOME CONTENT TO SHOW FULL-SIZE IMAGE<img src='base_path/{$images[$imageId]}' /><br>"; $output .= "{$prevLink} | {$nextLink}"; }
  11. 1 point
    Or use AJAX. Depends on what you're trying to accomplish and how you're trying to accomplish it. As far as the security goes, no matter what you do that part's going to be up to you, and I'd recommend not just blindly copy/pasting code from the internet in this situation.
  12. 1 point
  13. 1 point
    Put it into a hidden input with the rest of the form that I assume you're using. And you think that Javascript is? Spoiler: it isn't.
  14. 1 point
    Did you notice the link in my post? The one that goes to a page whose very first sentence is "Xdebug replaces PHP's var_dump() function for displaying variables"?
  15. 1 point
    Must be something you are doing. Post code for the benefit of the clairvoyantly challenged.
  16. 1 point
  17. 1 point
    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!
  18. 1 point
    licksdev.com and www.licksdev.com are two different sites. Set up a redirect so that one of them always goes to the other. So the user (eg, you) won't get confused by the two sites.
  19. 1 point
    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;
  20. 1 point
    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>
  21. 1 point
    here's an outline of what the logic would look like - $interval = 30; // booking/busy interval in minutes // based on conditional logic in the code, 0 = mon through 6 = sun define('MON',0); // use defined constants to make code/data self-documenting // working hours $hours = []; $hours[MON] = ["morning_from" => "closed", "morning_to" => "closed", "afternoon_from" => "13:00", "afternoon_to" => "19:00"]; // note: if you define the above array as an array of arrays, with the from/to values, a label (Morning/Afternoon), and a 'closed' or time entry, you can just loop over this to produce the output without needing to have specific code for each possible segment in a day // busy times - the example data is for a monday $busy = []; $busy[] = ["title"=> "Test", "start_date" => "2019-11-25 13:00:00", "end_date" => "2019-11-25 14:00:00"]; // pre-process the booked/busy data $data = []; foreach($busy as $arr) { $date = $arr['start_date']; $end_date = $arr['end_date']; while (strtotime($date) <= strtotime($end_date)) { $data[$date] = $arr['title']; $date = date("Y-m-d H:i:s", strtotime("$date +$interval min")); } } // examine the pre-processed booked/busy data echo '<pre>'; print_r($data); $current_date = '2019-11-25'; // determine the current date being displayed using whatever logic the code has now $book_day_int = date('N') - 1; // get the integer day of week number - 1 $current_day = $hours[$book_day_int]; // get the from/to data for the current day // morning output (see the note above by the $hours array to simplify and make the code general-purpose) $start = $current_day['morning_from']; $end = $current_day['morning_to']; if( $start != 'closed') { echo 'Morning<br>'; $start = "$current_date $start:00"; $end = "$current_date $end:00"; $date = $start; $end_date = $end; while (strtotime($date) <= strtotime($end_date)) { echo $date; // test if this date-time is busy if(isset($data[$date])) { echo ' ' . $data[$date]; } echo '<br>'; $date = date("Y-m-d H:i:s", strtotime("$date +$interval min")); } } // afternoon output $start = $current_day['afternoon_from']; $end = $current_day['afternoon_to']; if( $start != 'closed') { echo 'Afternoon<br>'; $start = "$current_date $start:00"; $end = "$current_date $end:00"; $date = $start; $end_date = $end; while (strtotime($date) <= strtotime($end_date)) { echo $date; // test if this date-time is busy if(isset($data[$date])) { echo ' ' . $data[$date]; } echo '<br>'; $date = date("Y-m-d H:i:s", strtotime("$date +$interval min")); } }
  22. 1 point
    It's not something you can set in your php.ini file, it's an apache directive not a PHP directive. Custom apache configurations are generally handled via a .htaccess file but only some directives are allowed in that file and as far as I know, this is not one of them. Godaddy would have to modify the vhost configuration for your site on their end to enable their directive and I doubt they would bother with that. Like I said before also, there is really not much point in enabling it. Essentially it just causes apache to do exactly the same thing as what you did in your original post, a DNS lookup on the REMOTE_ADDR. So if you really wanted to, you could just do it yourself via: $_SERVER['REMOTE_HOST'] = gethostbyaddr($_SERVER['REMOTE_ADDR']);
  23. 1 point
    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.
  24. 1 point
    If there were such a thing, every spammer would be using it.
  25. 1 point
    No. Validating on the user's computer means telling it what to do and hoping that it happens. You must validate on the server, and you may validate on the client too. That sounds like a good reason to not only do validation on the client. Because your code and/or design is flawed. Handle it in whatever way you want as long as it works the way you need it to work.
  26. 1 point
    Short fuse? I've taken the time to respond multiple times providing the same information which you ignore because you've got some preconceived notions in your head that you can't get rid of. Think of it this way, someone is taking time out of their day to try and help someone for no reason other than goodwill - there is no compensation for their time. Yet, the person they are trying to help ignores/disregards the help being provided such that the person providing the help invests even more time and energy helping that person. So, who is the "nutter" in this scenario? The person that is attempting to help or the person that won't take the time to try and understand the help being provided? You are "terrible" at this because you are not taking the time to understand the process. Instead you seem to be throwing things at the wall to see what will stick. Let's try one more time: Your requirement is to delete a record three days after the user performs some event (which I assume is a logout). Is this correct? 1) You first need to perform an action when the user selects the option to logout. As stated many times, you would want to set a datetime/timestamp value for the record. STOP HERE. Is there something about that statement that you do not 100% understand? Do you understand why the record would need to be updated and why we would use a datetime/timestamp value for that update? If you are not 100% clear, ask a question about that. You've previously provided info that when this action takes place the user_id is available in the session data. So, we would accomplish the above action like so: //Create a prepared statement with placeholder for the user_id of the record to be updated $stmt = $dbc->prepare("UPDATE users SET logout_datetime = NOW() WHERE user_id = ? "); //Bind the user_id value to the prepared query and execute it $stmt->bind_param('i', $_SESSION['user_id']); $stmt->execute(); STOP HERE. Do you understand all of the code above? If not, ask a question about what you don't understand or look at the manual for any function you don't understand. 2) Now that users will have a datetime/timestamp value set when they log out, there needs to be a separate process that will delete the records after three days. To accomplish this, you would create a separate script which will need to be executed on a regular basis (e.g. daily). You will need to check your host options o how to do this. Typically these will be called CRON jobs. You basically set up a scheduled task to run a script at a predetermined interval. STOP HERE. Do you understand what was just stated? If not ask a specific question. If you don't know how to create a CRON job, you need to go into your hosting options, check help and/or contact support. Once you know how to create a CRON job, you just need to create the script that will run every day (or whatever time interval you choose). Since we have a datetime/timestamp of when users have logged out, a single query can be executed to delete all records where that value is > 3 days (as has been provided previously) $query = "DELETE FROM users WHERE logout_datetime < (DATE(NOW()) - INTERVAL 3 DAY)"; //No user_id $stmt = $pdo->query($query) STOP HERE. Do you understand what that query is doing and why user_id is not needed? This is my last attempt. I hope you will READ the above information and attempt to comprehend it. If you have any questions that show that you have put some energy into trying to trying to figure this out instead of just haphazardly writing new code, I will try to answer. Otherwise, I which you all the best in your endeavors.
  27. 1 point
    if I were you I'd use a newline (\n) to separate the data instead of "@@@". if(isset($_POST['textdata'])) { file_put_contents('data.txt', $_POST['textdata']."\n", FILE_APPEND); } Then, if you data.txt file contains, say TESTA TESTB TESTC TESTD ... you can read it back and separate the items into an array using file(); $data = file('data.txt'); giving $data = Array ( [0] => TESTA [1] => TESTB [2] => TESTC [3] => TESTD )
  28. 1 point
    Pity. If you had read on you'd have seen he is writing to a text file.
  29. 1 point
    Turn your error reporting ON
  30. 1 point
    <input type="checkbox" name="checkboxes[]" value="whatever you want">
  31. 1 point
    +----+ +------+ | It | | Just | +----+ +------+ | | +-----+ +-----+ | can | | add | +-----+ +-----+ | | +----+ +---------+ | be | | spaces. | +----+ +---------+ | +-------+ | done. | +-------+
  32. 1 point
    It's more complicated, but yes it can be done in Notepad. You just need to add spaces in the necessary spots to get the boxes to align how you want them.
  33. 1 point
    Also, escaping in and out of HTML like this is kinda old fashioned. These days you may want to keep your HTML separate from PHP. Personally I limit myself to placing only variables in my HTML. So, no conditional logic in the HTML itself, which makes it very clean and easy to maintain. If using heredoc, you can use curly brackets around variables. I.e.: $tpl_content = array('title' => 'test', 'article_body' => 'hallo world'); $template = <<<_TEMPLATE_ <!doctype html> <html> <head> <title>{$tpl_content['title']}</title> </head> <body> <article> <header> <h1>{$tpl_content['title']}</h1> </header> {$tpl_content['article_body']} </article> </body> </html> _TEMPLATE_; // End of Template I wish I had learned this early on myself, as it could have saved me many hours of spaghetti hell.
  34. 1 point
    I can see I have been talking to myself. I have better things to than waste more time on you.
  35. 1 point
    If your problem is how to output tab separated data with column names /* SAMPLE DATA +-------+-------+---------+------------+ | empid | fname | lname | dob | +-------+-------+---------+------------+ | 1 | Peter | Smith | 1985-01-26 | | 2 | Paul | Hartley | 1973-12-02 | | 3 | Mary | Baker | 1980-04-11 | | 4 | Jane | Doe | 1990-11-28 | +-------+-------+---------+------------+ */ $res = $db->query("SELECT empid , fname , lname , dob FROM employee; "); echo '<pre>'; $row = $res->fetch(PDO::FETCH_ASSOC); echo join("\t", array_keys($row)) . "\n"; // headings do { echo join("\t", $row) . "\n"; // data } while ($row = $res->fetch()); echo '</pre>'; Which gives Similarly, if you want to write it to a csv file for export to Excel, then $res = $db->query("SELECT empid , fname , lname , dob FROM employee; "); $fp = fopen('AAA.csv', 'w'); $row = $res->fetch(PDO::FETCH_ASSOC); fputcsv($fp, array_keys($row), "\t"); // headings do { fputcsv($fp, $row, "\t"); // data } while ($row = $res->fetch());
  36. 1 point
    Use ids, not names, to link records. TABLE: user +----+----------+------------+ | id | username | leader_id | +----+----------+------------+ | 1 | fred | 2 | | 2 | mo | NULL | | 3 | brian | 2 | | 4 | john | 2 | | 5 | peter | 1 | | 6 | curly | 1 | | 7 | joan | 1 | | 8 | Dennis | 6 | +----+----------+------------+ Recursion is your friend here. $res = $db->query("SELECT id , username , leader_id FROM usertest order by leader_id "); $users = []; // store users in array for each leader foreach ($res as $r) { $users[$r['leader_id']][] = [ 'id' => $r['id'], 'username' => $r['username'] ]; } echo '<pre>'; listStaff(null, $users, 0); // list staff for leader "null" echo '</pre>'; /** * recursive function to list staff * * @param int $id * @param array $users * @param int $level */ function listStaff($id, &$users, $level=0) { $indent = str_repeat("\t", $level); foreach ($users[$id] as $u) { // for each of their staff echo "$indent{$u['username']}<br>"; // outout the name if (isset($users[$u['id']])) { // if they have staff listStaff($u['id'], $users, $level+1); // list their staff } } } Giving mo fred peter curly Dennis joan brian john
  37. 1 point
    if you use exceptions for database statement errors and in most cases let php catch and handle the exception, php will use its error related settings to control what happens with the actual error information (database errors will 'automatically' get displayed/logged the same as php errors.) you will be able eliminate the existing error handling, rather than to convert it. to enable exceptions for errors for the mysqli extension, add the following line of code before the point where you make the database connection - mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); now the bad news, it is not enough to just update statements in old code, as one of the things that was removed in php5.4, magic_quotes, eliminated some protection that php provided against sql special characters in external string data from breaking the sql query syntax (which is how sql injection is accomplished.) if your code does not have specific protection for all external/unknown data, and for all the different data types, being put into sql queries, you will need to add it. the simplest, universal way of doing this is to use prepared queries, provided that you switch to use the simpler PDO extension. the prepared query interface for the mysqli extension is overly complicated and inconsistent
  38. 1 point
  39. 1 point
    As to the manual, "die" is an alias of "exit" which is a function, and there are examples in the manual which you should try on a standalone script first, so you learn how to call functions with the appropriate syntax. https://www.php.net/manual/en/function.exit.php Also i would recommend to not just randomly copy and paste function signatures into production code and hoping that they work as you expect, but actually learn how PHP works and what syntax is needed from the examples.
  40. 1 point
    About 15 years ago I wrote a function to produce this from data very much like yours EG SELECT * FROM horse; +----+------+------+------+----------+ | id | name | sire | dam | gender | +----+------+------+------+----------+ | 26 | A | 27 | 39 | STALLION | | 27 | B | 28 | 40 | STALLION | | 28 | C | 29 | 40 | STALLION | | 29 | D | 30 | 40 | STALLION | | 30 | E | 31 | 41 | STALLION | | 31 | F | 32 | 41 | STALLION | | 32 | G | 33 | 42 | STALLION | | 33 | H | 33 | 42 | STALLION | | 34 | I | 35 | 43 | STALLION | | 35 | J | 36 | 43 | STALLION | | 36 | K | 37 | 44 | STALLION | | 37 | L | 38 | 44 | STALLION | | 38 | M | 34 | 45 | STALLION | | 39 | N | 29 | 46 | MARE | | 40 | O | 27 | 51 | MARE | | 41 | P | 28 | 51 | MARE | | 42 | Q | 29 | 50 | MARE | | 43 | R | 30 | 50 | MARE | | 44 | S | 31 | 49 | MARE | | 45 | T | 32 | 49 | MARE | | 46 | U | 33 | 48 | MARE | | 47 | V | 34 | 48 | MARE | | 48 | W | 35 | 46 | MARE | | 49 | X | 36 | 46 | MARE | | 50 | Y | 37 | 47 | MARE | | 51 | Z | 38 | 47 | MARE | +----+------+------+------+----------+ It uses a recursive* function which gets the sire and dam for the horse $id and outputs the name. It then calls itself for the sire and the dam which outputs their names and get their parents. This is repeated until the specified level of ancestry is reached. Is that the sort of thing you are trying to do? If so, give it a go using the method I described and come back if oyu get stuck * recursion : see recursion
  41. 1 point
    Okay. Then see the link in my first reply.
  42. 1 point
    I assume you've had a go at it yourself by now. Here's my effort... <?php $data = []; for ($r=0; $r<4; $r++) { for ($c=0; $c<4; $c++) { $data[$r][$c] = rand(0,1); } } $rowcounts = $colcounts = []; for ($r=0; $r<4; $r++) { $rowcounts[$r] = count(array_keys($data[$r], 1)); } for ($c=0; $c<4; $c++) { $colcounts[$c] = count(array_keys(array_column($data,$c), 1)); } $rmax = max($rowcounts); $cmax = max($colcounts); $rcmax = max($rmax, $cmax); $hirows = array_keys($rowcounts, $rcmax); $hicols = array_keys($colcounts, $rcmax); echo "<table border='1' style='border-collapse:collapse'>\n"; for ($r=0; $r<4; $r++) { echo "<tr>"; for ($c=0; $c<4; $c++) { $hilite = (in_array($r, $hirows) || in_array($c, $hicols)) ? 'class="max"' : ''; echo "<td $hilite>&nbsp;{$data[$r][$c]}&nbsp;</td>"; } echo "</tr>\n"; } echo "</table>\n"; ?>
  43. 1 point
    Comment when and where it's necessary. When it comes to methods, I'm a fan of always writing documentation but at least document the parameters, regardless the scope of the method - I've heard people say it's only important to document the public API of a class. This is utter bullshit. However, when it comes to initial documentation for a class if it does something weird, then yeah - document that sucker. For instance, your Formatter class seems simple enough - it formats a thing. However, if you're not using namespaces and your system formats both HTML and JSON, but Formatter only deals with JSON then document that. I'd argue you should use namespaces or rethink your class naming scheme, but sometimes you come into legacy code and have to do what you have to do.
  44. 1 point
    I don't put comments on classes. They tend to be somewhat self-explanatory just by reading the (namespace and) name alone. Unless there's something particular complicated about them... but most of the time any complexity is with what that happens inside a method. But definitely put comments on the methods.
  45. 1 point
    Looking for help with what part, exactly? Are you not sure what the SELECT query should be? Having problems integrating it into the code and displaying the results?
  46. 1 point
    SOLUTION: In order for the client to work over SSL you need to set the server certificate and private key and start a secure server as follows. Please see here: https://github.com/ratchetphp/Ratchet/issues/609#issuecomment-363743604
  47. 1 point
    I believe I may have it. $originalstart = date("Y-m-d"); $originalstart = date("Y-m-d",strtotime('-24 months', strtotime($originalstart))); for( $i= 0 ; $i <= 25 ; $i++ ) { $start = date('Y-m-01',strtotime('+'."$i".' month', strtotime($originalstart))); $firstday = date('Y-m-d', strtotime('next Sunday', strtotime('last Friday', strtotime('first day of last month', strtotime($start))))); $lastday = date('Y-m-d', strtotime('next Saturday', strtotime('last Friday', strtotime('first day of this month', strtotime($start))))); echo "$firstday - $lastday<br />"; } 2017-10-01 - 2017-10-28 2017-10-29 - 2017-11-25 2017-11-26 - 2017-12-30 2017-12-31 - 2018-01-27 2018-01-28 - 2018-02-24 2018-02-25 - 2018-03-31 2018-04-01 - 2018-04-28 2018-04-29 - 2018-05-26 2018-05-27 - 2018-06-30 2018-07-01 - 2018-07-28 2018-07-29 - 2018-09-01 2018-09-02 - 2018-09-29 2018-09-30 - 2018-10-27 2018-10-28 - 2018-12-01 2018-12-02 - 2018-12-29 2018-12-30 - 2019-01-26 2019-01-27 - 2019-02-23 2019-02-24 - 2019-03-30 2019-03-31 - 2019-04-27 2019-04-28 - 2019-06-01 2019-06-02 - 2019-06-29 2019-06-30 - 2019-07-27 2019-07-28 - 2019-08-31 2019-09-01 - 2019-09-28 2019-09-29 - 2019-10-26 2019-10-27 - 2019-11-30
  48. 0 points
    Sorry by my clairvoyance is not working today. Perhaps if you posted some code it might help. Be sure to use the code icon (<>) and select PHP.
  49. 0 points
    If you are selling warships, why not indeed. Whatever your application requires.
  50. 0 points
This leaderboard is set to New York/GMT-05:00
  • Newsletter

    Want to keep up to date with all our latest news and information?
    Sign Up
×
×
  • 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.