-
Posts
4,207 -
Joined
-
Last visited
-
Days Won
209
Community Answers
-
Jacques1's post in Can you tell my why this doesn't work? was marked as the answer
Because of operator precedence. Concatenation binds stronger than assignments, so PHP first builds the string
1 . '. ' . $myArray[$i] . '<br />'; and then "adds" that string to the counter, which discards everything but the leading 1.
Of course the real answer is: Don't do this. Precedence is tricky enough (parentheses can help here), but when the expressions also have side effects, even a seemingly simple piece of code can lead to all kinds of bugs. Don't try to save lines of code.
-
Jacques1's post in help with php and database was marked as the answer
Read the manual. Can you see the big red warning sign which says that the function has been removed? This is not a joke. All mysql_* functions are absolete since almost 15(!) years. Whatever tutorial or book told you got this from, throw it away and look for recent information. We're using PDO now.
-
Jacques1's post in create table; datetime default value current_timestamp + was marked as the answer
How about you stop posting “blah blah blah” and actually get to the point?
So, what's your problem? The manual clearly says that you need at least version 10.2.1 for the above feature. That's a hard fact. Since you don't want triggers, this leaves you with exactly two choices:
Upgrade your MariaDB. Give up and simply store the current timestamp. You can still add the 10 minutes in your application. -
Jacques1's post in First Post: Output remote server stream bash file with line breaks on page PHP was marked as the answer
It's a shell script. Not sure what's so confusing about that.
OP: What do you need the newline sequences for? The Bash echo already terminates each string with a newline. However, PHP scripts by default output HTML, and an ASCII newline is not an HTML newline. Either change the content type of the HTTP response to text/plain or use a <pre> element or convert the newlines to <br> elements.
-
Jacques1's post in Display a group within a group was marked as the answer
You'll make your life a lot easier if you first turn the result set into a more convenient format and then render that custom format. For example:
[ '100x100' => [ 'bob@example.com' => [ $bob_donation_1, $bob_donation_2, // ... ], 'sue@example.com' => [ $sue_donation_1, $sue_donation_2, // ... ] ], '150x200' => [ // ... ], ] This can be rendered with a simple nested foreach loop rather than a complex state machine.
Pre-processing the result set is also trivial.
donations = [] for each row in result_set: donations[row["width"] + "x" + row["height"]]["email"][] = all_donation_related_data_you_need -
Jacques1's post in Problem with Submit button was marked as the answer
Looks like you're writing your code with a completely inappropriate tool (Microsoft Word?) which replaces straight quotes with typographic quotes:
" -> ” HTML parsers have no idea what to do with those.
Use a proper code editor or an IDE.
-
Jacques1's post in Pre-populating form from SQL using Session? was marked as the answer
The real problem is that you're jumping to advanced tasks before you've fully understood the basics, and you start writing code before you've finished the concept.
Learn the PHP basics first. Learn how to safely query the database with PDO and prepared statements. Learn the basics of security like HTML-escaping and password hashing. And most importantly: Actually think about what you're doing, don't just blindly copy and paste code you've found somewhere on the Internet. Does it really make sense to print internal error message on the website? Attackers will surely find this information useful, but legitimate users cannot do anything with it and will probably wonder what the hell is going on. Does it really make sense to repeatedly fetch rows with a loop when you know there's exactly one row?
Start small and build your application from the ground up. Simply copying and pasting code fragments may yield quick results at first, but what's the point of all that code when most of it is garbage and you have no idea what it even does?
Secondly, make a plan before you start typing. You don't need walls of diagrams, but you should at least have a basic idea of where this is going. Trial and error doesn't work. Why do you even want to insert the username into a form field? Do you want the user to change it and submit the review under a different name? What's the point of that?
-
Jacques1's post in problem with parsing xml was marked as the answer
Do you see any references to $key or $value in your loop? Me neither. Then how do you expect to get the entries?
If you don't remember how loops work, relearn the PHP basics before you start any complex project.
-
Jacques1's post in How to show the Timedifference? was marked as the answer
There's no such feature in MySQL. The DATEDIFF() function gives you calendar days and has nothing to do with time.
Use the DateTime class in your application.
<?php const MYSQL_DATETIME_FORMAT = 'Y-m-d G:i:s'; $input = '2017-07-31 19:15:74'; $now = new DateTime(); $input_datetime = DateTime::createFromFormat(MYSQL_DATETIME_FORMAT, $input); $diff = $now->diff($input_datetime); echo $diff->format('%d days, %H hours, %I minutes, %S seconds'); -
Jacques1's post in Validating a form. Cant validate right? was marked as the answer
Dude.
Stop – writing – random – PHP – code. Stop it. No code. I don't need your code. I need you to start thinking.
You said you understand the idea, but you clearly don't, so let's try that again in plain English:
You take one parameter at a time. Not two. Not three. One. One parameter. If the parameter doesn't exist, then you display an error message. If it does exist, you check if it's empty. In case of an empty parameter, you display another error message. That's the procedure for one parameter. Now you have two. A dumb approach would be to randomly try different combinations and hope that one of them is right. You did that, and it failed. The smart approach is to simply do one step after the other: First you validate one parameter, then you validate the next. No combinations. Just a sequence of checks.
Do you think you can write pseudo-code (not PHP code) for two checks?
Of course this can later be optimized with loops etc., but right now, the goal is to understand the procedure.
-
Jacques1's post in Total Time Not Displaying Correctly was marked as the answer
Hint: 0.5 hours are 30 minutes.
What you want is an integer division.
-
Jacques1's post in MySql Loop through a column to form concatenated string was marked as the answer
SQL is not a replacement for all programming languages. Rendering data or processing it in special ways is still performed by the application, not the database system.
So select the groups/dimensions/… you need, turn the data into a convenient format (like an array of arrays), then build the word combinations with PHP (or whatever language you happen to prefer).
<?php $texts = ['A', 'year old', 'is']; $values = [ [20, 30, 40], ['Man', 'Woman'], ['fresher', 'experienced'], ]; foreach (cartesian_product(...$values) as $combined_values) { $line = ''; foreach ($combined_values as $i => $value) { if ($i > 0) { $line .= ' '; } $line .= html_escape($texts[$i], 'UTF-8').' '.html_escape($value, 'UTF-8'); } echo $line.'<br>'; } <?php // this is a naive recursive implementation; if you have a lot of data, you may need a more efficient solution function cartesian_product($head, ...$tail) { if (!$tail) { return array_map(function ($item) { return [$item]; }, $head); } else { $prod = []; $prod_of_tail = cartesian_product(...$tail); foreach ($head as $left_item) { foreach ($prod_of_tail as $right_items) { $prod[] = array_merge([$left_item], $right_items); } } return $prod; } } function html_escape($raw_text, $encoding) { return htmlspecialchars($raw_text, ENT_QUOTES | ENT_SUBSTITUTE, $encoding); } -
Jacques1's post in array multidimensional error was marked as the answer
This doesn't make sense. Just leave the exception alone and turn display_errors on during development, then PHP will print the error message and all relevant information on the screen.
There's no point in adding and then removing a try statement only to print the message. PHP can do that much better than you.
So -- problem fixed?
-
Jacques1's post in NOW() + Days was marked as the answer
Look at your query:
'NOW() + INTERVAL 3 DAY' This is a string. You're trying to insert the literal text “NOW() + ...” as a date value, and that's of course nonsense.
What you want to insert is the result of a calculation:
NOW() + INTERVAL 3 DAY An even smarter approach would be to simply store the current date and then calculate the end date dynamically when it's actually needed.
-
Jacques1's post in help displaying record info was marked as the answer
First the standard decontamination procedure:
Your code has SQL injection vulnerabilities all over the place. Not only can this be used to compromise your database or even the entire server. It also leads to syntax errors with perfectly valid input. Learn to use prepared statements. Your error handling is messed up. First you dump your connection error straight on the website, which is really helpful for attackers and very irritating for legitimate users. Then you just stop checking for errors altogether. Learn how to enable exceptions and then let PHP handle them. mysqli is actually a poor choice. It's a cumbersome low-level interface for people who read the manual, and we all know this doesn't work for PHP programmers. If you can, switch to PDO. It's far more programmer-friendly and supports many different database systems, not just MySQL. You have no input validation whatsoever. You don't check the request method, you don't check if the parameters are actually present, you don't check if their values make sense. This makes the application extremely fragile and difficult to debug, because invalid values aren't caught and may have all kinds of unexpected effects. Maybe the application crashes at some point, maybe it continues but doesn't do what it should. You never know. Learn to validate all input.
If you're still having trouble, post the full code (leaving out the relevant fetch parts is rather silly) in code tags (not this custom colored text stuff) and with a concrete error message.
-
Jacques1's post in SQL update statement parameter list or individual. was marked as the answer
There seem to be several misunderstandings.
First, you definitely do not create a new connection or even PHP script for every single query. Why would you do that? You establish one connection and then run as many queries as you need in the main script or within functions.
<?php $connection = new mysqli(...); // one query $connection->query('...'); // another query $connection->query('...'); ... Secondly, you must not insert user input directly into query strings. This immediately leads to an SQL injection vulnerability and can compromise your database or even the entire server. Always use prepared statements with parameters when you need to pass dynamic values to a query.
Then you should seriously consider switching from mysqli to PDO which is far more programmer-friendly. If you insist on using mysqli, then you need to actually learn it (secure queries, proper error handling etc.).
If you fix all this, there's really no reason for special code to handle UPDATE queries. In fact, I strongly recommend against that. You may save a few lines with a generalized update routine, but there's a huge risk of introducing new vulnerabilities and bugs through the dynamic queries. Just use plain old prepared statements with static query templates.
-
Jacques1's post in Best way to identify chat user to send message to was marked as the answer
Using a member ID as the message target is fine, unless you don't want to expose this information for some reason.
I'm not sure what your “random temporary keys” are supposed to do. Your chats are effectively just private messages, so the user or group ID is the only information needed. The WebSocket server knows all current connections and also knows (or should know) the user behind each connection, so you can simply send the message to the corresponding TCP socket(s).
-
Jacques1's post in SELECT COUNT JOIN GROUP BY issue not showing all empty counts was marked as the answer
You're grouping by the item's client ID which is NULL whenever a client has no items. You need to group by c.id.
-
Jacques1's post in Checking variables was marked as the answer
Those are Yoda conditions which are supposed to catch programming errors where the assignment operator = has been used instead of the equality operator == or ===. With the normal order, both $x = 1 and $x == 1 are valid, so there's a chance you might miss the mistake. But with the reversed order, 1 = $x is invalid, so you would immediately see the problem.
However, I think this has turned into a stupid mannerism. It's hard to read, it tries to solve a problem that barely exists (how often do you mix up = and ===?), and it's just unnecessary when you use a proper IDE which can do those checks for you. If some code conventions demand it, go ahead, otherwise I would avoid it.
-
Jacques1's post in Is there a better solution to storing this data in mysql table? was marked as the answer
If you have lots of data, there will be lots of rows. That's unavoidable. However, that doesn't mean there's a problem.
Database systems were in fact made for handling large amounts of data, and “large” means billions of rows and terabyte-sized tables. There's a difference between the data you expect (or are hoping for) and the actual data. Experience shows that the number of users or the amount of activity tends to be exaggerated. -
Jacques1's post in How to access multiple json arrays with single variable? was marked as the answer
How are we supposed to tell you what you want? There are multiple senders and received amounts, and you've picked the first one while ignoring the rest. This could be horribly wrong or exactly right, depending on what you actually want to do.
In any case, your code is rather weird. What's the point of iterating over the transactions, storing the various items in new arrays and then iterating over those arrays to finally do the checks? Why not just check the transactions directly? This is basic programming:
<?php // let's use a more sensible name than $get_address to hold the transactions $last_received_transactions = $block_io->get_transactions(['type' => 'received', 'addresses' => $my_wallet]); $transaction_id_matches = false; foreach ($last_received_transactions->data->txs as $transaction) { if ($transaction->txid == $_POST['trans-id']) { $tx_id_matches = true; } // other checks go here } if ($transaction_id_matches) { echo 'transaction ID found'; } else { echo 'transaction ID not found'; } -
Jacques1's post in Secure Login and Page Thesedays was marked as the answer
I don't think you understand how sessions work.
Sessions are stored server-side, usually as files. Users cannot access those files, let alone change them. Maybe you're confusing sessions and cookies.
Of course there are attacks against sessions, but none of them is prevented by your random IDs. So the approach is just useless.
-
Jacques1's post in regex not working was marked as the answer
Your regex doesn't say that at all. You have no anchors (which means a substring match is sufficient), and for some strange reason you're using preg_match_all(), as if you expected multiple matches.
If you only want to allow dashes and dots as delimiters between alphanumerics, that's
'/\\A[a-z\\d]+(?:[.-][a-z\\d]+)*\\z/i' Length checks are the job of strlen() or mb_strlen().
-
Jacques1's post in How to subtract current time with database time? was marked as the answer
So do you want future records or past records? Your code and your description say two different things.
In any case, filtering is done with the WHERE clause, not in the application. And, yes, MySQL understands the concept of time.
... WHERE date >= NOW() -- only current and future records; adjust if necessary -
Jacques1's post in Inserting Date&Time FORM in database was marked as the answer
Neither PHP nor MySQL can read your mind. You can't just throw an arbitrary timestamp format at them and assume they'll magically figure out what you mean.
Fumbling with Unix timestamps is also a bad idea, because you're effectively converting a relative timestamp (relative to the default PHP timezone) to an absolute Unix timestamp and then back to a relative timestamp (relative to the MySQL default timezone). There's no guarantee whatsoever that you'll get back the original timestamp. In fact, you probably haven't even thought about time zones and DST yet.
The correct approach is to explicitly specify the format that should be parsed and RTFM for the right MySQL format.
<?php // your custom input format to be parsed by DateTime::createFromFormat() const INPUT_TIMESTAMP_FORMAT = 'd.m.Y H:i'; // the MySQL format to be created by DateTime::format() const MYSQL_TIMESTAMP_FORMAT = 'Y-m-d H:i'; // test timestamp $_POST['date'] = '13.4.2017 21:16'; // parse the input timestamp according to its specific format $gameTimestamp = DateTime::createFromFormat(INPUT_TIMESTAMP_FORMAT, $_POST['date']); // now you can convert the timestamp to the MySQL format and insert it $mysqlGameTimestamp = $gameTimestamp->format(MYSQL_TIMESTAMP_FORMAT); var_dump($mysqlGameTimestamp);