Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 07/22/2024 in Posts

  1. Highly recommend switching to a library like PHPMailer or SwiftMailer - they're both easier to use and more reliable than php's native mail function.
    2 points
  2. the most common reason for a password_hash()/password_verify() to fail is because the database column is not long enough to hold the hashed value. another common reason are programming mistakes in the form/form processing code and a lack of server-side validation that results in the hash value not actually being from the password that was submitted in the registration code, or the value being used in the login code not being what you think it is. your post method form processing code should always trim the input data, mainly so that you can detect if all white-space characters were entered, then validate all inputs before using them.
    2 points
  3. the file system path/filename must be to where the file is located on the disk, either using a relative path (relative to the file with the include/require starting in it) or an absolute path. a leading / refers to the root of the current disk, which is doubtful where that file is located, and which will be producing a php error about a non-existent path/file. you must get php to help you by reporting and displaying all the errors it detects. you can temporarily set php's error_reporting/display_errors in your code (you will want to remove the settings when you are done learning, developing, and debugging). you can add the following immediately after the first opening <?php tag in the main file - ini_set('display_errors', '1'); error_reporting(-1);
    2 points
  4. I'd do something like this... <?php $data = [ '46.105.73.18:27015' => [ 'gq_address' => '46.105.73.18', 'gq_dedicated' => '', 'gq_gametype' => '', 'gq_hostname' => '', 'gq_joinlink' => 'steam://connect/46.105.73.18:27015/' , 'gq_mapname' => '', 'gq_maxplayers' => '', 'gq_mod' => '', 'gq_name' => 'Counter-Strike: Source' , 'gq_numplayers' => '', 'gq_online' => '', 'gq_password' => '', 'gq_port_client' => 27015 , 'gq_port_query' => 27015 , 'gq_protocol' => 'source' , 'gq_transport' => 'udp' , 'gq_type' => 'css' , 'players' => Array (), 'teams' => Array () ] ] ; $tdata = ''; foreach ($data as $k => $v) { $v = array_filter($v); // get rid of blank values $tdata .= "<table border='1'> <tr><th>Array key</th><th>" . join('</th><th>', array_keys($v)) . "</th></tr>\n"; // output headings $tdata .= "<tr><th class='rowth'>$k</th><td>" . join('</td><td>', array_values($v)) . "</td></tr> // output values </table>\n"; } ?> <html lang='en'> <head> <meta 'charset'='utf-8'> <title>Example</title> <style type='text/css'> table { border-collapse: collapse; margin-bottom: 10px; } th { background-color: #444; color: white; padding: 8px; } .rowth { background-color: #888; } td { padding: 8px; text-align: center; } </style> </head> <body> <?= $tdata ?> </body> </html> Giving ...
    2 points
  5. First step to manually parsing HTML is to stop manually parsing HTML. Use DOM instead.
    2 points
  6. After about 3 hours of waiting I killed the process as the SQL server never showed a status other than "idle". I think it hit a problem and got itself into an infinite loop doing nothing. To give myself some data to work with, I managed to extact the table structure , the first 3,400 and the last 600 records from the sql file. I could have done all of them but it (thankfully) uses multiple row inserts (1700 at a time) and it takes an age scrolling through the text to find each block's start and end then select the block. There are about 200 such blocks and each takes about 2.5 seconds to load the data - so the whole load should have taken 8-9 minutes. Enough of the excuses. I finally came up with a solution using the post table. The first part (WITH ...) creates a temporary table called "plast" which contains a row for each threadID with the latest date of all the posts for the thread. The main part of the query (SELECT ...) matches the threadid/latest date with the post table to find the matching post and also joins to the thread table to pick uo thread info. Finally, I limit the output to just those dates in the last 7 days. (Apologies for screwing up the text encoding along the way - eg "Jürgen Peters". It's only test data.) WITH plast AS ( SELECT threadID , MAX(time) as latest FROM wbb1_1_post GROUP BY threadID ) SELECT t.threadID , t.topic , p.userID , p.username , p.postid , FROM_UNIXTIME(p.time) AS time , FROM_UNIXTIME(plast.latest) AS latest FROM wbb1_1_post p JOIN wbb1_1_thread t ON p.threadID = t.threadID JOIN plast ON plast.threadid = p.threadid AND plast.latest = p.time WHERE FROM_UNIXTIME(p.time) > CURDATE() - INTERVAL 7 DAY ; +----------+----------------------------------------------------------------+--------+------------------+--------+---------------------+---------------------+ | threadID | topic | userID | username | postid | time | latest | +----------+----------------------------------------------------------------+--------+------------------+--------+---------------------+---------------------+ | 131549 | welche Spinne? --> eventuell Lepthyphantes sp. | 5455 | Manfred Zapf | 507256 | 2025-01-26 10:08:19 | 2025-01-26 10:08:19 | | 131698 | Baumwanze | 1397 | zobel | 507259 | 2025-01-26 12:48:43 | 2025-01-26 12:48:43 | | 56659 | Grüne Futterwanze? | 15196 | Christine | 507261 | 2025-01-26 14:57:09 | 2025-01-26 14:57:09 | | 131576 | Kleine schwarze Spinne --> Enoplognatha cf. thoracica | 15395 | Bernd 07 | 507263 | 2025-01-26 16:01:45 | 2025-01-26 16:01:45 | | 131307 | Amaurobius fenestralis? --> bestätigt | 15395 | Bernd 07 | 507264 | 2025-01-26 16:08:09 | 2025-01-26 16:08:09 | | 131701 | Unbekannte Schneckenart | 15395 | Bernd 07 | 507267 | 2025-01-26 16:43:50 | 2025-01-26 16:43:50 | | 131702 | Encyrtidae? | 11406 | JohnEs81 | 507268 | 2025-01-26 17:00:37 | 2025-01-26 17:00:37 | | 131700 | Welche Wanze ist das? --> Arocatus longiceps | 15395 | Bernd 07 | 507272 | 2025-01-26 17:36:02 | 2025-01-26 17:36:02 | | 131699 | Tegenaria --> nein sondern Amaurobius similis/fenestralis | 1999 | Klaus Fritz | 507274 | 2025-01-26 17:48:07 | 2025-01-26 17:48:07 | | 131683 | Grüne Larve -> Geometridae Art | 11406 | JohnEs81 | 507280 | 2025-01-26 20:41:49 | 2025-01-26 20:41:49 | | 131703 | eine Acericerus heydenii? | 1 | Jürgen Peters | 507282 | 2025-01-26 20:45:32 | 2025-01-26 20:45:32 | | 131687 | Zygina nivea? | 15392 | Sascha_N | 507286 | 2025-01-26 21:15:21 | 2025-01-26 21:15:21 | | 131686 | Welcher Schnellkäfer? --> Melanotus sp. | 15395 | Bernd 07 | 507287 | 2025-01-26 21:29:11 | 2025-01-26 21:29:11 | | 131693 | Lispocephala brachialis --> bestätigt | 15800 | Bernd Cogel | 507293 | 2025-01-26 22:06:16 | 2025-01-26 22:06:16 | | 131704 | Cantharis paradoxa? --> Cantharis sp., ein schwarzer, immerhin | 15335 | Simeon Indzhov | 507295 | 2025-01-26 22:29:15 | 2025-01-26 22:29:15 | | 131695 | Peyerimhoffina gracilis? | 15335 | Simeon Indzhov | 507296 | 2025-01-26 22:36:08 | 2025-01-26 22:36:08 | | 131705 | Phytoecia coerulescens? | 1 | Jürgen Peters | 507297 | 2025-01-26 22:52:48 | 2025-01-26 22:52:48 | +----------+----------------------------------------------------------------+--------+------------------+--------+---------------------+---------------------+ Are you planning on rebuilding the database?
    2 points
  7. you are doing 'date-ination'. it's like pagination, but using dates. you should be using a get request to determine what will be displayed on the page. this is so that if someone finds a result they would like to return to or share, they can bookmark or share the URL and can return to the same result. the dates you pass in the URL should be a standard YYYY-MM-DD format. format the dates as 'l j M' only when you display them. you would default to the current monday if there is no get input. you would produce the previous/next links with the previous/next monday's date and include any existing get parameters so that if you add other search/filters, they will automatically get propagated in the URL between pages. example code - <?php date_default_timezone_set('America/Denver'); // default to the current monday if there is no get input if(!isset($_GET['fdw'])) { $dw = new DateTime('monday this week'); $fdw = $dw->format('Y-m-d'); } else { // you should validate that the get input is a properly formatted date - code left up to you $fdw = $_GET['fdw']; } // use $fdw in your code to produce the output $dw = new DateTime($fdw); echo $dw->format('l j M') . '<br>'; // get a copy of any existing get parameters $get = $_GET; // produce the previous link // calculate previous date $dw = new DateTime($fdw); $pw = $dw->modify('-1 week'); $pfdw = $pw->format('Y-m-d'); // set the fdw element $get['fdw'] = $pfdw; // build the query string part of the url $qs = http_build_query($get,'','&amp;'); echo "<a href='?$qs'><button>< Previous Week</button></a>"; // produce the next link // calculate next date $dw = new DateTime($fdw); $nw = $dw->modify('+1 week'); $nfdw = $nw->format('Y-m-d'); // set the fdw element $get['fdw'] = $nfdw; // build the query string part of the url $qs = http_build_query($get,'','&amp;'); echo "<a href='?$qs'><button>Next Week ></button></a>";
    2 points
  8. It might work a little more cleanly in PHPStorm, but when I tried it in VS Code, I found it much more complicated to try to select text or read through code when the editor was injecting those things into the view. Maybe if they weren't inline, though I can't imagine how not, they might be nicer for me... But I'm also a proponent of the idea that you should be able to tell what the parameter is, be that through a variable name or an obvious literal value (or a constant...), and if you can't tell then you should do something about that. // this is obvious on what the parameters are password_verify($password, $hashedPassword) // this is not password_verify($value, $row[1])
    2 points
  9. Judicious application of array key names can greatly increase the efficiency and simplicity of your code. Consider this simplified version of the questions/options form code <form method='post' > <?php for ($qno=1; $qno<=2; $qno++) { echo <<<HTML <label> Sub Question $qno <span class="req">*</span> <textarea cols="46" rows="3" name="Q[$qno][question]" placeholder="Enter Sub question here.."></textarea> </label> <ul> HTML; for ($opt='A'; $opt<='D'; $opt++) { echo <<<HTML <li>Choice $qno$opt (text)&nbsp; <input type='text' name="Q[$qno][opts][$opt]" placeholder="Enter Choice A here.." size='40'> </li><br><br>\n HTML; } echo "</ul><hr>\n"; } ?> <input type='submit'> </form> producing... When the form is submitted, the POST array is like this... Array ( [Q] => Array ( [1] => Array ( [question] => aaaaaaaaaaaaaaaaaaaaaaaaaaa [opts] => Array ( [A] => aa [B] => bb [C] => cc [D] => dd ) ) [2] => Array ( [question] => bbbbbbbbbbbbbbbbbbbbbbbbb [opts] => Array ( [A] => ww [B] => xx [C] => yy [D] => zz ) ) ) ) Now you can easily iterate through the array to write the questions/options to you database foreach ( $_POST['Q'] as $qno => $qdata ) { write $qno and $qdata['question'] to question table save last insert id as $qid foreach ( $qdata['opts'] as $ono => $choice ) { write $qid, $ono, $choice to choice table } } Job Done.
    2 points
  10. Unchecked checkboxes are not posted. I prefer to use a the null coalescing operator (??) when handling checkboxes EG $Bold = $_POST['Bold'] ?? 0; //if not set, default to '0'
    2 points
  11. I had to create my own test data (thanks for that) but naturally I don't know how it conforms with yours. TABLE: product TABLE: bookingItem +----+-------------+-----------+--------+ +----+-----------+---------------------+---------------------+----------+ | id | productName | category | status | | id | productid | startTime | endTime | quantity | +----+-------------+-----------+--------+ +----+-----------+---------------------+---------------------+----------+ | 1 | Room 1 | Guestroom | Active | | 1 | 1 | 2024-01-01 11:32:01 | 2024-01-02 11:32:59 | 1 | | 2 | Room 2 | Guestroom | Active | | 2 | 2 | 2024-02-01 11:34:08 | 2024-02-03 11:34:24 | 2 | | 3 | Room 3 | Guestroom | Active | | 3 | 3 | 2024-03-01 11:34:56 | 2024-03-04 11:35:08 | 3 | | 4 | Room 4 | Guestroom | NULL | | 4 | 2 | 2024-04-01 12:20:20 | 2024-04-07 12:20:41 | 6 | | 5 | Room 5 | Guestroom | NULL | | 5 | 3 | 2024-05-01 01:21:49 | 2024-05-05 12:21:58 | 4 | +----+-------------+-----------+--------+ | 6 | 5 | 2024-06-19 12:23:03 | 2024-06-29 12:23:28 | 10 | | 7 | 2 | 2024-06-01 13:02:51 | 2024-06-15 13:03:16 | 14 | +----+-----------+---------------------+---------------------+----------+ On running your code with my data I get these results for Q1 and Q2. I have written the correct totals in red. As you can see there is a distinct pattern - your totals are the correct totals squared. However, I could not spot any multiplication in the code (I ran as separate query to confirm the correct totals) I have to say, in your code you really make a meal of those dates in the years and quarters considering that SQL can handle it easily. Here's my version... <?php ############################################### # CREATE YOUR OWN PDO DATABASE CONNECTION # # # require 'db_inc.php'; $pdo = mdbConnect('db1'); # # # # ############################################### $range = [ '2020-01-01', '2024-07-31' ]; $selectedYear = $_GET['year'] ?? 0; $whereYear = ''; if ($selectedYear) { $whereYear = 'AND YEAR(d.dt) = ?'; $range[] = $selectedYear; } $res = $pdo->prepare("WITH RECURSIVE dates(dt) AS ( SELECT ? UNION ALL SELECT dt + INTERVAL 1 MONTH FROM dates WHERE dt < ? ) SELECT YEAR(d.dt) AS yr , QUARTER(d.dt) as qtr , MONTHNAME(dt) AS mth , productName AS room , COALESCE(SUM(DATEDIFF(endTime, startTime)), '-') AS nights FROM product p CROSS JOIN dates d LEFT JOIN bookingitem b ON b.productid = p.id AND YEAR(d.dt) = YEAR(b.startTime) AND MONTH(d.dt) = MONTH(b.startTime) WHERE p.`status` = 'Active' $whereYear GROUP BY yr, qtr, MONTH(d.dt), p.id "); $res->execute($range); $results = $res->fetchAll(); $rooms = array_unique(array_column($results, 'room')); $theads = "<tr><th>Quarter</th><th>Month</th><th>" . join('</th><th>', $rooms) . "</th><th>Total</th></tr>\n"; ### RESTRUCTURE THE RESULTS ARRAY foreach ($results as $r) { $data[$r['yr']][$r['qtr']][$r['mth']][$r['room']] = $r['nights']; } ?> <!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 { width: 100%; border-collapse: collapse; } th { background-color: #808080; color: white; padding: 8px; } td { padding: 4px 12px; text-align: right; } .ca { text-align: center; background-color: #EEE; } .la { text-align: left; background-color: #EEE; color: black; } </style> </head> <body> <header class='w3-indigo w3-padding w3-margin-bottom'> <h1>Guestroom Occupancy</h1> </header> <div class='w3-content w3-padding'> <?php ## OUTPUTFROM RESTRUCTURED ARRAY foreach ($data as $yr => $ydata) { echo "<h3>$yr</h3>\n <table border='1'> $theads "; foreach ($ydata as $qtr => $qdata) { $span = 3 + count($rooms); echo "<tr><th class='la' colspan='$span'>Quarter {$qtr}</th></tr>\n"; foreach ($qdata as $mth => $mdata) { echo "<tr><td>&nbsp;</td><td>$mth</td><td>" . join('</td><td>', $mdata) . "</td><td><b>" . array_sum($mdata) . "</b></td></tr>\n"; } } echo "</table>\n"; } ?> </div> </body> </html> Output
    2 points
  12. the above line is missing any { }, so the only line of code that gets executed for an is_dir() is the - echo '<strong>'.$directory .'</strong> <br>'; all the rest of the lines get executed regardless of what $directory is. i recommend that you always format your code so that you can see when it is actually doing.
    1 point
  13. E_DEPRECATED and E_USER_DEPRECATED are the same thing, with the one difference that the former is used by the engine and the latter is used by trigger_error. So the question is in what environments do you care/not care about getting messages about using deprecated features and functionality?
    1 point
  14. Don't. PHP isn't a low-level language like C. You don't have to manage memory like that. PHP has some very smart internal logic and is perfectly capable of handling creating and destroying variables on your behalf. So let it do what it knows how to do.
    1 point
  15. Correct. That is an invalid mysql date. You can set a mode of mysql to accept that value, but that is not the way to handle this problem. Instead, make sure that the OTP expiry allows NULL. Then set the value to NULL. Personally, I would not design a system like this. Instead I would have a related table that only holds "events". I will usually have an user_event_type table that has different allowable authentication events. For example: user event type id | Description 1. Registration 2. Password Reset 3. One time Password 4. Login 5. Close account 6. Failed Login 7. Account locked etc. I don't know what your user table looks like but hopefully it has an ID other than "email". I'll assume you do. So you then have a user_event table with a structure like this: id | user_id | user_event_type_id | event_value | status | expire_date_time | created_at 100| 245 | 3 | xyzabc... | 0 | ..... | current_date There are a few reasons to do this. They include: - you have an audit trail of events - MySQL with InnoDB is optimized for insert queries, and they don't reduce concurrency unlike update queries. Instead of trying to overwrite the OTP, you can simply set the status from 0 to 1 (or whatever value you want). You could have several status values if you want fine grain control over the changes in status. Just to keep it simple, if the person logs in with the OTP, then it's used, so you set the status to 0. A subsequent query of "SELECT * FROM user_event WHERE user_id = 245 and user_event_type = 3 AND status = 0 ORDER BY created_at DESC LIMIT 1" will always find the most recent OTP request. You can then compare that with the OTP value. Making event_value a varchar of a specific length is no cost if the field is unused, as varchars will use the bytes required. So if you want to use event_value for additional data, you can do that, but if it's something simple like "login" event, you don't need to use it. Personally I would also have a client_ip field in a table like this, where I use a varbinary field to store the IP. This works for both IPv4 and IPv6 addresses, but there are some tricks to doing that, and it is not specifically related to your question. I mention it just to be complete.
    1 point
  16. you still have not provided any context (meaning) of this data. name-numbered, labels and variables, are meaningless to us. if the mix of rows shown in the example picture is valid, i.e. you can have have any number of rows from each html table section, you should (probably) store the data from each row in each html table as a separate row in the detail database table, with an item_id column to indicate the meaning of each row of data. i have a recommendation for the dynamically added markup. don't write out the markup in the javascript yourself, where you have to keep it updated to match any changes or corrections (you are going to need to eliminate the use of duplicate ids) you make to the markup being output on the page. instead, define/store the output being output on the page in a php variable, so that you can echo it on the page and echo it as the markup inside the javascript. if you use back-ticks (template literals) around what you echo in the javascript, you can use the exact same markup in both cases. see this link - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
    1 point
  17. Hi No offense taken at all ; I was just annoyed at myself with the fact that I spent most of last night debugging something, that seemingly fixed itself next morning (as is often sadly the case) Thats propably why my reply seemed angry. I apologize. As for the actual problem I have no idea what caused the initial behaviour. Now I get perfectly reasonable results regardless of whether i use cURL or file_get_contents; I therefore thought it was fitting to mark your reply as the solution, since: was exactly what was needed. Best, David
    1 point
  18. Hi CBG, Logical switches do not work like spoken words and it is easy to misunderstand them. What you really want to check is that if any one of d,c,o is yes, then error. But PHP is obeying your instructions by stopping when anyone of them is No. You need to switch the OR to an AND and it will catch the one Yes that is not allowed: <?php $p = "Yes"; //yes is different than Yes $d = "No"; $c = "No"; $o = "No"; if ($p === "Yes" && $d !== "Yes" && $c !== "Yes" && $o !== "Yes") { echo "error"; exit; } echo 'no errors'; ?> which will display an error if all three (d,c,o) are No. Otherwise, the code will display no errors. but what are you doing when a lowercase y is used? yes instead of Yes. maybe you should also use lowercase and compare with strtolower().
    1 point
  19. what this would look like using the method i posted above - <input type="text" maxlength="32" size="42" name= "<?=$Comment_Name?>" value="<?=$_SESSION["DE_Retain"] == 1 ? $_SESSION["DE_Comment"] : ''?>">&nbsp;&nbsp;Max 32 Characters<br><br> likewise for the checkbox logic - Retain comment:&nbsp;<input type="checkbox" maxlength="1" size="1" name="Retain" <?=$_SESSION["DE_Retain"] == 1 ? 'checked' : ''?>> i'm pretty sure that checkboxes don't have maxlength or size attributes. if any of these variable may not exist, to prevent php errors, you need to use the null coalescing operator ?? to set default values. if you want to clear all the session data, you can use session_destroy();. if you only want to clear this 'form' data you are passing around, while keeping the current user logged in, you should store this data in a session array variable, such as $_SESSION['post']. you can then clear this data by just unsetting it - unset($_SESSION['post']);
    1 point
  20. after reviewing the code more, let me introduce you to 'event delegation'. this will let you simplify all the code for attaching events to the buttons. this works by attaching the event to a parent container, such as the div with class='right-content', that all the buttons will exist in, regardless of when they are created. you would then find which button has been clicked by testing an attribute value from the button, such as a class name. the code would look like - document.addEventListener("DOMContentLoaded", function() { console.log("✅ DOM fully loaded and parsed."); // use event delegation for dynamically added elements (buttons) // attach the event to a common parent element - class='right-content' const buttonWrapper = document.querySelector('.right-content'); // add the click event to everything in the common element, now or in the future buttonWrapper.addEventListener('click', function (event) { // examine the className of the clicked element console.log('target class: ',event.target.className); switch(event.target.className) { case 'view-details-btn': view_details(event.target); break; case 'change-status-btn': openStatusModal(event.target); break; case 'update-notes-btn': openNotesModal(event.target); break; case 'delete-btn': deleteRenewal(event.target); break; case 'closeModal': document.getElementById(event.target.getAttribute("data-modal-id")).style.display = "none"; break; case 'confirmChangeStatus': confirmChangeStatus(event.target); break; case 'confirmUpdateNotes': confirmUpdateNotes(event.target); break; } }); });
    1 point
  21. the php error you are getting is a follow-on error, because the query is failing, but there is no error handling for the query. the easiest way of adding error handling for all the mysqli statements that can fail - connection, query, exec, prepare, and execute, is to use exceptions for errors (this is the default setting now in php8+). to enabled exceptions for the mysqli extension, add the following line of code before the point where you make the database connection (or upgrade to php8) - mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); you should then be getting an uncaught exception error with the raw database error information in it about a non-groupby/non-aggerate column being referenced. the correct way of fixing this is to a) only select the columns you are using, and b) every column you are selecting needs to be either in the GROUP BY term or used in an aggerate function. there is a database server mode setting that control if this condition produces a query error (the current setting) or if it is just a warning. you may or may not have access to this database mode setting.
    1 point
  22. First an editorial comment: Please do not take screen shots of code for your questions. We can't use that in our replies or help. We have a code block for a reason. You can easily copy/paste snippets of relative code into the code block, and that makes it possible for us to make edits based on the original code. Nobody here likes having to re-type parts of your code. Paths in your html are relative to the document root. The document root is a function of the web server configuration for the server or vhost you have configured. The types of things you can refer to in an html script are only things that the server understands to have an associated URL. In other words, they are things that you could use a url to access directly from your website. PHP works entirely with files, and file system paths on your workstation. Using PHP code to open include/require files always requires a file system path. When you include a file, the "working directory" for PHP is the path/location in the server file system where the script exists. So to include a php script from another php script you have 2 options: Provide the fully qualified path to the script. Because this path is operating system dependent, you typically don't want to do this as it requires you to add configuration in a file or even edit your source code purely because you moved servers. A Relative Path This is relative, again to the directory where the script that is including this code is. Relative paths can utilize 2 "special files": "." is the current directory. ".." is the parent directory. We don't know what the file system layout is for your project, so we can only guess at the correct path relative to the index.php? or whatever file it is that you are trying to do this php include in is named. If this directory has a sub-directory named "page" and you have put the site-header.php script into that directory, then the relative path you want to use will be: include("page/site-header.php"); This is how you specify a subdirectory path relatively. If you include a leading "/" that is considered the "root" directory of the filesystem. One other thing you might want to do is change include to require_once(). With a require_once() the script will actually error out rather than continue to run along without regard to the fact that your include failed.
    1 point
  23. Hi jtorral, I think that, based upon your posted four-point problem, responsive css is a better method than trying to use php to respond to media sizes. https://developer.mozilla.org/en-US/docs/Web/HTML/Responsive_images media queries can also help for images or overall css adjustments for "other functions on the page like resizing pop up boxes and so on" https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries when you veer away from JavaScript driven pop-up dialogs and move to css modal methods, the above methods will save you alot of hassle, such as trying to post to an included php file and expecting it to receive the post. Have a look at the css and try that method instead. The session should be used to maintain state, which includes databases by storing a user id for repeated querying. You could post CSS questions in the CSS Help forum: https://forums.phpfreaks.com/forum/17-css-help/ And have a second look at what Gizmola posted, John
    1 point
  24. Thank you. You should know that i have a text file of data that you have posted. I always appreciate the wisdom from the top talent here at phpfreaks. I have learned alot from this forum and its top members. I give credit where credit is due. I actually learned how this JOIN is working and i have successfully implemented my own query on the db last night before bed. I'll post the code in a reply to Barry. My point is that i learn from Barry and not simply take code and be on my way. I'm not looking for a free ride, only help when something is above my current level of knowledge. I hope that you have a splendid day, Gizmola.
    1 point
  25. I'm sure he does know that, and we are both motivated by an interest in mentoring and passing along our expertise to people like yourself if we are able. We appreciate the feedback.
    1 point
  26. i recommend giving the fields a class name. you can then eliminate the array and just use getElementsByClassName to get a collection of the elements to loop over. see if this gets you closer to what you want - <html> <head> </head> <body> <script> function hasNumericValue() { const matches = document.getElementsByClassName("numeric"); for (let i = 0; i < matches.length; i++) { alert(Number.parseInt(matches[i].value)); } } </script> <form name="tester" method="post" action="" onsubmit="return hasNumericValue();" > <input name="it_c" type="text" class='numeric' value=""> <br> <input name="it_h" type="text" class='numeric' value=""> <br> <input name="ot_c" type="text" class='numeric' value=""> <br> <input name="ot_h" type="text" class='numeric' value=""> <br> <input type="submit" value="submit"> </form> </body> </html> you can then test if each value is or is not a number.
    1 point
  27. Barry is truly a master of relational database design, implementation and SQL. However , at least initially, a small investment on your part in learning how to join tables together, will dramatically improve your understanding of his analysis and the SELECT statement he provided you. I browsed this material and it's a solid free tutorial on Joins using MySQL. https://www.mysqltutorial.org/mysql-basics/mysql-join/ You may see references to ANSI standard SQL, which is a standard for portable SQL syntax that should be compatible with most relational databases, but I did want to mention that different databases will have features that are specific to their implementation (non-standard), so you might see that in the case of joins there is more than one syntax possible, but they all do the same things. Don't let that confuse you -- JOINS are an essential concept that all relational databases implement. If you have an option, and can use ANSI standard syntax, opt for that, but it really doesn't matter that much, so long as you are clear on what the join produces. A basic understanding of Set theory might give you some insight into the ideas that went into relational database management (union, intersection, difference, subset) might help as well. This article cover the topic pretty well, and you may notice some of the overlap in concept and terminology: https://kyleshevlin.com/set-theory/ It's also worth learning how to read an Entity-Relationship-Diagram (ERD). Once you understand the fundamentals, you should be able to look at an ERD and understand how tables can be joined together. There are also many tools that people use to design or reverse engineer databases. For example, mysql provides ERD design features in their free SQL Workbench tool. ERD's are the way that people socialize a database design, and are the documentation that teams use to document for developers, the database design.
    1 point
  28. Yes! If you have each post with its time_posted then you can alway s find the times of first and last posts without storing those dates. Basically, do not store derived data like those dates or totals. Also the thread table contains usierID and username - username belongs only in the user table, not repeated in every thread record for that user. The dats/times are stored as unix timestamps. Horrible and completely unreadable. Use the inbuilt date/time/datetime/timestamp type columns.
    1 point
  29. Your UNIQUE key is the combination of (slug, tag_check). NULL values are ignored and your insert query always writes NULL to tag_check column. CREATE TABLE `dupe_test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `slug` varchar(50) NOT NULL DEFAULT '', `tag_check` tinyint(4) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `player_tag_check` (`slug`,`tag_check`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; select * from dupe_test; +----+-----------+-----------+ | id | slug | tag_check | +----+-----------+-----------+ | 1 | hugh-jass | NULL | | 2 | hugh-jass | NULL | | 3 | hugh-jass | NULL | | 4 | hugh-jass | 1 | +----+-----------+-----------+ Add another... MariaDB [test]> insert into dupe_test (slug) values ('hugh-jass'); Query OK, 1 row affected (0.051 sec) MariaDB [test]> select * from dupe_test; +----+-----------+-----------+ | id | slug | tag_check | +----+-----------+-----------+ | 1 | hugh-jass | NULL | | 2 | hugh-jass | NULL | | 3 | hugh-jass | NULL | | 6 | hugh-jass | NULL | << NEW | 4 | hugh-jass | 1 | +----+-----------+-----------+ 5 rows in set (0.000 sec) Now try adding again but with tag_check = 1 then 2... MariaDB [test]> insert into dupe_test (slug, tag_check) values ('hugh-jass', 1); ERROR 1062 (23000): Duplicate entry 'hugh-jass-1' for key 'player_tag_check' MariaDB [test]> insert into dupe_test (slug, tag_check) values ('hugh-jass', 2); Query OK, 1 row affected (0.073 sec) MariaDB [test]> select * from dupe_test; +----+-----------+-----------+ | id | slug | tag_check | +----+-----------+-----------+ | 1 | hugh-jass | NULL | | 2 | hugh-jass | NULL | | 3 | hugh-jass | NULL | | 6 | hugh-jass | NULL | | 4 | hugh-jass | 1 | | 8 | hugh-jass | 2 | +----+-----------+-----------+ 6 rows in set (0.000 sec) So either insert a tag_check value too, or exclude tag_check from the UNIQUE key
    1 point
  30. Going on what mac_gyver said, which is spot on, First, you need to define the roles that your application will support. For example, you might have roles like admin, editor, and viewer. $roles = [ 'admin' => ['create', 'edit', 'delete', 'view'], 'editor' => ['edit', 'view'], 'viewer' => ['view'] ]; Next, you will need to assign these roles to your users. This can be done in your database. For simplicity, let's assume you have a user array that includes their role. $users = [ 'user1' => ['role' => 'admin'], 'user2' => ['role' => 'editor'], 'user3' => ['role' => 'viewer'] ]; Before allowing access to a specific page or functionality, you should check if the user has the required permissions based on their role. Here’s a simple function to check permissions: function hasPermission($userRole, $action) { global $roles; return in_array($action, $roles[$userRole]); } Now, you can use the hasPermission function to control access to different parts of your application. For example: session_start(); $currentUser = $_SESSION['user_id']; // Assume the user_id is stored in session $userRole = $users[$currentUser]['role']; if (hasPermission($userRole, 'edit')) { // Allow access to edit functionality echo "You have access to edit."; } else { // Deny access echo "Access denied. You do not have permission to edit."; } Hope this makes sense and may help you somewhat.
    1 point
  31. If you are wanting to know which keyword(s) is/are found, there is one flaw in your logic - it exits the function on the first keyword found. What if there are two or more keywords that are found? Instead of returning true on the first keyword found, I'd suggest adding the found keywords to an array. Then return the array. Also, I would assume you would want to do a case insensitive search. E.g. if you have "spamword1", you would want a match on something like "SpAmWoRd1". If so, you would want to use stripos() Give a look at this: $uri = $_SERVER['REQUEST_URI']; $spam_keywords = [ 'spamword1', 'spamword2', 'spamword3' // WILL BE A LOT MORE HERE ]; function checkKeywords($uri, $keywords) { $foundKeywords = array(); //Create array to hold found keywords foreach ($keywords as $keyword) { //Iterate over list of keywords if (stripos($uri, $keyword) !== false) { //Check if keyword is in $uri $foundKeywords[] = $keyword; //Add found keyword to array } } //Return found keywords return $foundKeywords; } //Check for keywords $foundKeywords = checkKeywords($uri, $spam_keywords); //Check if results are not empty if (!empty($foundKeywords)) { //Keywords were found - display them echo "<p>The following Keywords were found:" . implode(', ', $foundKeywords) . "</p>"; } else { //No keywords found echo "keywords not found"; }
    1 point
  32. Here's an example. As you enter more letters of the name it narrows down the resulting list. (first and last names are searched) <?php # # HANDLE AJAX REQUESTS # if (isset($_GET['ajax'])) { if ($_GET['ajax'] == 'names') { $res = $pdo->prepare("SELECT id , concat(fname, ' ', lname) as name FROM person WHERE fname LIKE ? OR lname LIKE ? ORDER BY fname, lname "); $res->execute([ $_GET['search'], $_GET['search'] ]); $results = $res->fetchAll(); exit(json_encode($results)); } } ?> <!DOCTYPE html> <html lang="en"> <head> <title>Example</title> <meta charset="utf-8"> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> <style type='text/css'> </style> <script type='text/javascript'> $(function() { $("#search").on("input",function() { let srch = $(this).val() + "%" $.get( "", {"ajax":"names", "search":srch}, function(resp) { $("#person").html("") $.each(resp, function(k,v) { let opt = $("<option>", {"value":v.id, "text":v.name}); $("#person").append(opt); }) }, "JSON" ) }) }) </script> </head> <body> <form> Enter first part of name: <input type='text' id='search' > <br><br> <select name='person_id' id='person' size='20'> <!-- names returned from search go here --> </select> </form>
    1 point
  33. you would use a typeahead/autocomplete/autosuggest input field, using ajax to get a list of matching people, that the user can then click on one to select it.
    1 point
  34. So you want something like this: foreach ($tokenArr as $val) { //... current code // bottom of foreach loop if ($errMess !== '') { break; } }
    1 point
  35. You only need one query. For example TABLE : product +----+-------------+--------------+--------+ | id | productName | category | status | +----+-------------+--------------+--------+ | 1 | Room 1 | Guestroom | Active | | 2 | Room 2 | Guestroom | Active | | 3 | Room 3 | Guestroom | Active | | 4 | Room 4 | Guestroom | Active | | 5 | Function 1 | Functionroom | NULL | +----+-------------+--------------+--------+ code $sql = "SELECT SUM(status='Pending')as pending , SUM(status='Active') as active FROM product"; $result = mysqli_query($con, $sql); $row = mysqli_fetch_assoc($result); echo "Pending : <input type=\"button\" class=\"button\" value=\"{$row['pending']}\"> Active : <input type=\"button\" class=\"button\" value=\"{$row['active']}\"> "; output
    1 point
  36. You need to give is some information as to what the actual issue is. Otherwise nobody can or will help you. Another good tip is to encase your code into the <> tag so it shows like this: <?php // database.php require_once __DIR__ . '/config.php'; // Ensure this path correctly points to config.php /** * Establish a new database connection. * * @return mysqli The MySQLi database connection object. * @throws Exception if the connection fails. */ function db_connect() { // Use MySQLi to connect to the database $connection = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); // Check if the connection was successful if ($connection->connect_error) { error_log("Database connection failed: " . $connection->connect_error); die("Database connection failed. Please check the error log for details."); } // Set the character set to UTF-8 for proper handling of characters if (!$connection->set_charset("utf8mb4")) { error_log("Error setting character set utf8mb4: " . $connection->error); } return $connection; } /** * Close an existing database connection. * * @param mysqli|null $connection The connection object to close. * @return void */ function db_disconnect($connection) { if ($connection instanceof mysqli) { $connection->close(); } } // Establish a connection and store it in the variable $db for use later $db = db_connect(); // You can now use $db for your database queries It makes it easier to read. Also, no need for this: if ($connection instanceof mysqli) { $connection->close(); } PHP automatically closes connections. Okay, your turn
    1 point
  37. Outside the webroot - whether that's called www/ or http/. The whole point is that you don't want the casual browser to be able to access the files directly, only php can access them. So from within the webroot you'll use something along the lines of include_once('../includes/myPhpFile.php'); The contents of myPhpFile are now accessible from the calling script.
    1 point
  38. Hello folks! I am new here. Nive to join the community.
    1 point
  39. I'm guessing the assignment deadline has passed, so for the sake of others reading the thread, here's one solution... <?php $a = 1; $b = 2; $c = []; $d = []; $N = 8; $tdata1 = $tdata2 = ""; $vals = []; for ($i=1, $a=1, $b=2; $i<=$N; $i++, $a+=2, $b+=2) { $c[] = $a; $d[] = $b; $exp = '<u>' . join('.', $c) . "</u><br>" . join('.', $d); $tdata1 .= "<td>$exp</td>"; $val = number_format(array_product($c) / array_product($d), 5) ; $tdata2 .= "<td>$val</td>"; } ?> <table border='1'> <tr><th>Fraction</th> <?=$tdata1?> </tr> <tr><th>Decimal</th> <?=$tdata2?> </tr> </table>
    1 point
  40. ... or ... $res = $pdo->query("SELECT Lvl , Sub FROM shadd_1 ORDER BY Lvl DESC, Sub "); $results = $res->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_COLUMN); foreach ($results as $lvl => $arr) { echo "$lvl <UL>"; foreach ($arr as $sub) { echo "<li>$sub</li>"; } echo "</ul>"; } FYI - the $results array (slightly simpler than the $data array in above post) looks like this.. Array ( [ULE] => Array ( [0] => BASIC lug [1] => BASIC lug ) [ACE] => Array ( [0] => ger ) )
    1 point
  41. There is an example near the end of the documentation for last_insert_id. Something like this I am guessing. $sql = " UPDATE $table SET item=?, id=LAST_INSERT_ID(id) WHERE id<10 ORDER BY id ASC LIMIT 1; "; //and then $last_id = mysqli_insert_id($conn); echo "Last inserted ID is: " . $last_id;
    1 point
  42. Are you still with us? requinix is a pro. You are in good hands. Meantime, margins is interesting because do you want margins or not? I see a double break after the body tag. <body><br><br/> incidentally, html5 does not require the ending slash. vide xhtml. since you are already using css, why not add margin control? <span style="font-family:'Comic Sans MS', Comic, Monospace; margin: 8px 8px"> the center tag is deprecated, is it not? Again, why not use css? align: center; text-align: center; let us know if you need further assistance. I will also post the entire script from the google drive link. I hope that it is okay to do so. Please forgive me if it is not okay to post the aftenrenlille.php code. <?php ini_set('default_socket_timeout', 5); ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>AU-INFO</title> <style type="text/css"> #dagensret{ //font-size:10px; } .food{ // color: green; font-size:15px; } </style> </head> <body><br><br/> <span style="font-family:'Comic Sans MS', Comic, Monospace"> <center> <span style="font-size:25pt"> <?php // 11 // remember to remove the ; from the beginning of extension=php_soap.dll in php.ini $cli= new SoapClient('https://xxxxxxxxxxx.dk/SPService.asmx?WSDL'); //$res = $cli->__soapCall('DagensMenu',array()); // $xmlstr = $res->DagensMenuResult->any; $simple = simplexml_load_string($xmlstr); $text = $simple->Menu->Tekst; echo "AFTENRENGØRING "; echo $text.""; ?> <!--Overskrift--> <span style="font-size:10pt"> <!--Overskrift--> <!--Vegatare--> <span style="font-size:25pt"> <!---> <?php $simple = simplexml_load_file('https://xxxxxxxxxxx/SPService.asmx/AktuelleOmraadeRengoering'); $text = $simple->Aktivitet->Navn; // slette + tegn AU $text = str_replace('+', '', $simple->Aktivitet->Navn); echo $text; ?> </body> </html> <!--Menu herover--> </html>
    1 point
  43. Don't use "select *". Specify the columns you need. Then use a foreach loop, not a for loop. Don't embed variables in the sql string, use prepared queries with placeholders, then execute with the variables passed as parameters. $sql_list = "SELECT ID FROM dados_socios WHERE usuario = ? ORDER BY ID"; $result_list = $conn->prepare($sql_list); $result_list->execute([$usario]); echo "<select>"; foreach {$result_list as $row) echo "<option>ID: {$row['ID']}</option>"; } echo "</select>";
    1 point
  44. PHP runs on the server. - Javascript runs on the client. On completion of the PHP it sends the page to the client where the javascript runs. At the time you "echo $array;" the js variable "i" does not yet exist. (Error thrown if turn on error reporting) By the time the javascript runs "$array" no longer exists.
    1 point
  45. if data is static and you are positive that this is the code that you wish to implement, then your logic needs to change from less than two to a more precise identifier. A switch will work better for you and allow you to adjust the code if you add more items to the array (which should not contain curly braces, rather square brackets). <?php $data=["egg","york","pork"]; $total = count($data); for ($i = 0; $i < $total; $i++) { switch ($i) { case 0: echo '<p>SECTION A<br>'; break; case 2: echo '</p>SECTION B<br>'; break; } echo $data[$i] . '<br>'; } $data2 = (array) ['Section A' => (array) ["egg","york"], 'Section B' => (array) ["pork"]]; foreach ($data2 as $section => $array) { echo '<p>' . $section . '<br>'; foreach ($array as $type) { echo $type.'<br>'; } echo '</p>'; } ?> but i recommend that you build your arrays to structure and identify data, then looping will be easy and the resulting code will be cleaner and more logical. vide data2 array and the subsequent code above.
    1 point
  46. It's all good my friend, we appreciate you being a part of the forum.
    1 point
  47. Once your page hits the browser there is nothing php can do. Any further client-side processing will require javascript. When page has loaded, set a timer ( see setTimeout() ) to initiate a process which hides your loading bar.
    1 point
  48. Answers to my questions would be nice too. "ftpd" is very likely going to be an FTP server. If you need it then you should look into what's wrong, if you don't then you can shut it down. It kinda sounds like the http and https sides are running with different user credentials. Except that's weird.
    1 point
  49. First, click on the error notification and sort out the error. Then try again.
    1 point
  50. 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
    1 point
This leaderboard is set to New York/GMT-04:00
×
×
  • 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.