-
Posts
5,450 -
Joined
-
Days Won
175
Everything posted by mac_gyver
-
@dev_Gency, that's not what the OP is doing. Please read threads before replying.
-
since you finally posted the code producing the unexpected output, this is because your html markup is broken. you are not surrounding the value = '...' attribute completely/correctly with single-quotes, so the first space character becomes a stop character. in the markup.
-
this wouldn't have been assigned without some instruction covering the fundamentals you are expected to use to solve it. you would produce all combinations of seating arrangements, eliminating arrangements that violate the seating rules, leaving you with set(s) of arrangements that work.
-
that's because you are searching for %whereeverSPACEsomethingelse% this requires whateverSPACE... to exactly exist somewhere within a column value for a match to occur. did you see @ginerjm's reply above? you will either need to explode the string on the space characters, then dynamically build a term for the where clause for each word, then OR the resulting terms together or alternatively, you can use a full text search.
-
client-side validation is a nicety for legitimate visitors. since external data can be submitted to your server-side code from anywhere, can be set to anything, and cannot be trusted, you MUST validate all data on the server before using it. since you must do this, it doesn't pay to do more than just use the browser's built in form field checks in the client. also, from the point where you have checked in the client if a value doesn't exist (you would need to use ajax to do this), to the point on the server where you actually try to insert the data, the value(s) could have been taken, and the insert query error handling is place where this check must finally occur. in the server-side code, the correct way of detecting duplicates, in the case of multiple concurrent requests to your script, is to define the column(s) to be unique indexes, then simply attempt to insert the data, and detect if a duplicate index error has occurred. in the case of more than one unique column, it is after the insert query fails, that you would execute a select query to find which column(s) already contain the submitted values. your database design is duplicating the fullname in two tables. this creates a problem in that if anyone edits a value, you must insure that all occurrences are updated. you should avoid duplicating data in multiple tables. is there some reason that you cannot just use a single table for all this user information? also, since most people have a first name and a last name, you should store these in two separate columns to avoid ambiguity. is someone's name Ross Martin or Martin Ross? as to the server-side code, this is largely derived from the bad code examples at w3schools and there's nearly twice as much code as is necessary. instead, the server-side form processing code should - use an array for the user/validation errors, with the array index being the field name. keep the form data as an array in a php array variable, then use elements in this array variable throughout the rest of the code. detect if a post method form was submitted, rather than trying to detect if the submit button is set. trim all the data ONCE. since you will be keeping the data in a php array variable, you can do this using one single line of code. there's 11 trim() statements in that code for 4 pieces of data. validate all the data, storing the errors per item #1 on this list. after the end of all the validation logic, if the array holding the errors is empty, use the submitted data. don't (switch to) use $_REQUEST variables. use the variables you expect data in. also, you are validating the trimmed input data, but are using the un-trimmed data in the sql query. after you do items #2 and #4 on this list, you will only be using the trimmed data throughout the rest of the code. you ARE using a prepared query. do NOT also apply any _escape_string() functions to the data. this will result in the escape characters being inserted into the database, messing up the stored data. don't copy variables to other variables for nothing. this is a waste of your time typing. if you switch to use the much simpler PDO database extension, about half of the database lines of code will go away. you need error handling for all the database statements that can fail - connection, query, prepare, and execute. the only place where a user can recover from a database error is when inserting/updating duplicate or out of range value. this is the only case where you should have error handling logic in your code. if you use exceptions for database statement errors and only catch and handle the exception in this case, you can remove any existing error handling logic, simplifying your code. every redirect needs an exit/die statement after it to stop php code execution. the redirect upon successful completion of the post method form processing code should be to the exact same url of the current page, to cause a get request for that page. the comment/redirect is not clear if this is what the code is doing. if there are user/validation errors at item #6 in this list, the code would continue on to display the html document, redisplay the form, with any user/validation error messages, and repopulate the appropriate form field values with the submitted values, so that user doesn't need to keep entering the same values over and over. any dynamic value that you output on a web page needs htmlentities() applied to it to help prevent cross site scripting. to get a form to submit to the same page it is on, simply leave out the entire action attribute.
-
what exactly is the "it only display's" and "still just echo's" code that you are describing that is not working? also, you should use a get method form for searching and determining what data will be gotten and displayed on a page and the form should be 'sticky' so that it remembers what the existing search term is in case the user wants to just modify the search value and try again. doing this will be a necessity if your next step is to combine the search feature with the pagination from your last thread.
-
don't do that. it is NOT concurrent safe. when more than one instance of your code is requested, each instance will get the same starting value, increment it, and produce duplicate values. you should instead use an auto-increment column. you should also NOT use a loop to fetch data from a query that will at most return one row. just directly fetch the data. don't do this either. this is storing derived/duplicate data. instead, concatenate this when the data is queried for. then why isn't the value inside of single-quotes in the query? you should use a post method form when performing an action on the server, so that a search engine indexing your site won't trigger the actions. this code is also open to sql injection. use a prepared query when supplying external, unknown, dynamic values to a query when it is executed. there's no validation logic, that would prevent empty values from being used, and no error handling for the database statements, that would handle duplicate user data in the insert query.
-
because the user's authorization can change (promoted, demoted, banned) between page requests, you should always query on each page request to get the current user information/permissions.
-
that's not the correct call-time parameter usage for the msyqli_select_db() statement. the correct usage can be found in the php.net documentation. you can also select the database when you make the connection now, so there's generally no need to use a separate select db statement. if you arrived at this point by trying to convert old mysql_ based code to use the mysqli extension, simply by adding an 'i' to the function calls, this does not work. you must actually learn the correct usage for the mysqli statements. if you are converting old mysql_ based code, it is simpler and much better to skip over using the mysqli extension and use the PDO extension, because a huge problem with converting old code is the lack of security against sql special characters in data values breaking the sql query syntax, which is how sql injection is accomplished. the simplest way of adding security for all data types is to use a prepared query, which is very simple with the PDO extension, but more complicated and inconsistently handled with the mysqli extension.
-
firstly, these emails are NOT being sent from the email address that is entered in the form. they are being sent from the mail server at your web hosting and the From: and Return-path: email addresses must correspond to your web hosting. you can use the submitted email address as the Reply-to: address, after validating that it is exactly and only a validly formatted email address (checking that it contains an @ and a . is not sufficient.) your code is open to mail header injection, so, a bot script can basically build an email with anything and send it to any email address. the spam emails you are receiving are just the copy being sent to your To: email address. you MUST validate all inputs before using them. for the entered email address, after you have trimmed and validated that it is not an empty string, use php's filter_var with the FILTER_VALIDATE_EMAIL flag (do NOT use the FILTER_SANITIZE_EMAIL flag as it alters the value.) if the entered email address passes all the validation, use it in the Reply-to: mail header.
-
the subject in this thread is the same as in your previous thread, just with a different database extension and a different problem in why there's no output. i recommend that you continue this in the previous thread, since the PDO database extension being used in it is superior to the sqlsrv extension.
-
En anglais s'il vous plaît There's no code in your code to call the ReadData() function. The result you are getting is just the static html markup with the DataTable javascript/css applied to it.
-
Objects, Classes, Variables, Libraries and Functions
mac_gyver replied to LeonLatex's topic in MySQL Help
also, i think you are getting stuck on the form (words, appearance) and you are not getting to the function (meaning, usage.) you don't actually need to fully understand OOP or the whole PDO extension in order to use it. in your previous thread, i gave list of simple steps on converting existing mysqli based code to use the PDO extension. assuming that you understand what the mysqli code is doing now, this should almost be a no-think exercise. typical prepared query msyqli code, with a multi-row result set - $sql = "some sql query statement containing ? palace-holders for each value"; $stmt = $mysqli->prepare($sql); $stmt->bind_param('s', $some_string_value); $stmt->execute(); $result = $stmt->get_result(); // error now, because get_result depends on the mysqlnd driver // at the point of producing the output foreach($result as $row) { // use elements in $row here... } after converting to use the PDO extension - $sql = "some sql query statement containing ? palace-holders for each value"; $stmt = $pdo->prepare($sql); $stmt->execute([$some_string_value]); $result = $stmt->fetchAll(); // for a multi-row result set, you will typically WANT to fetch all the data at once, so that you can test, couunt, and loop over it as needed // at the point of producing the output foreach($result as $row) { // use elements in $row here... } -
Objects, Classes, Variables, Libraries and Functions
mac_gyver replied to LeonLatex's topic in MySQL Help
the PDO documentation section in the php.net manual https://www.php.net/manual/en/book.pdo.php is what you are looking for. the PDO acronym stands for PHP Data Objects and is found in the Introduction section. the most relevant, commonly used sections to learn first are - PDO constructor - makes a connection PDO query - executes a non-prepared query PDO prepare - prepare a prepared query PDO lastInsertid - gets the last insert id from an insert/update query PDOStatement execute - executes a prepared query PDOStatement various fetch methods - fetch, fetchAll, fetchColumn - fetches data from a select query PDOStatement rowCount - gets the number of affected rows from an insert/update/delete query PDOException - used when handling user recoverable errors in your application when you make the database connection using PDO, you should - set the character set to match your database tables, so that no character conversion occurs over the connection. set the error mode to use exceptions (i think i saw recently that this is the default now, but set it anyways.) the connection already always uses exceptions. the simplest application code will result if you also use exceptions for all the other statements that can fail - query, prepare, and execute and only attempt to handle exceptions in your code in the case of user recoverable errors, such as inserting/updating duplicate or out of range values. set emulated prepared queries to false, you want to use real prepared queries. set the default fetch mode to assoc, so that you don't have to specify it in each fetch statement. see the following post for typical connection code (end of the post) and converging a non-prepared query to a prepared query - -
actually, they are being appended to the end of the downloaded file. if you open the downloaded file in your programming editor, you should see that output. in the 'other' cases where you may have used those lines of code and they worked, you weren't downloading files, where you? the response that the web server outputs for a downloaded file - the http headers, followed by the file contents, can only be those two things. short-answer: you cannot redirect after the file download. if you do a web search on this, you will find that you first goto the desired final page, then use javascript on that page to make a http(s) request to the download link.
-
Objects, Classes, Variables, Libraries and Functions
mac_gyver replied to LeonLatex's topic in MySQL Help
MySQL AB was (past tense, currently owned by Oracle) the original developer of the MySQL database server, which implements their own variation of the Structured Query Language (SQL.) i am guessing your post above is asking about the documentation for MySQL? that can be found at https://dev.mysql.com/doc/refman/8.0/en/ . the most relevant sections for the SQL they implement would be in 13.2 Data Manipulation Statements, for SELECT, INSERT, UPDATE, and occasionally DELETE queries. other often used sections in the documentation are sections 9 - 12 language structure, character sets, collations, unicode, data types, and operators and functions. the SQL language that MySQL implements has nothing directly to do with php or the php extension (mysqli or PDO) you use. MySQL is a database server. Php is functioning as a client program, connecting to that server. after making a connection to the database server, you are building and sending SQL query statements to the server, retrieving, and using the result from the queries. the php database extension (mysqli or PDO) is just the means you are using within the php code to interact with the MySQL database server. -
Show a percentage based on values from a table
mac_gyver replied to AndyJones's topic in PHP Coding Help
what value do you need to calculate the percentage, the total number of votes? you just need to devise a method of getting that value from the fetched data in $rows. one method would be to loop over the data to add up the individual totals. another method would be to use php's array functions to operate on the data as a set - see php's array_column() and array_sum(). -
the php mysqli extension on your system must be compiled to use the mysqlnd driver, for the get_result and a few other functions/methods to be available - https://www.php.net/manual/en/mysqlnd.install.php i'm not sure this can be accomplished just through the hosting control panel. you will know when you are successful when there is a mysqlnd section in the phpinfo() output on your system. if you cannot enable this, your choices are, rewrite the code to - use the much simpler, more consistent, and better designed PDO extension. it has no mysqlnd driver gotya's like this. eliminate the use of the mysqli get_result function/method, which will require you to use mysqli_stmt::bind_result, and a bunch of code to dynamically fetch data as a result set or do a bunch of typing for all the columns/variables you are selecting from each query. however, if you are going to go through this much work, for each query, you might as well just spend the time to do item #1. converting a mysqli prepared query to use the PDO extension is fairly straight forward - make the database connection using PDO, storing the connection in a variable uniquely named, such as $pdo, so that you can identify/search which code has been converted or not. the use of ? positional prepared query place-holders is the same between mysqli and PDO. change the $mysqli->prepare() calls to use the $pdo connection variable, e.g. $pdo->prepare(). take the list of variables you are supplying to the ->bind_param() call, and supply them as an array to the ->execute([...]) call. remove the bind_param() calls and the get_result() calls. fetch the data using one of PDO's fetch methods - fetch(), fetchAll(), ... note: if you are using a foreach() loop to iterate over the msyqli result object (from the get_result call), you can loop over the PDO statement object in exactly the same way. for a non-prepared query, you would just use the PDO ->query() method instead of the mysqli ->query() method, then fetch/loop over the data as described above. any use of last insert id, num rows, or affected rows would need to use the equivalent PDO statements.
-
aside from that query needing the columns you are SELECTing listed, nothing about that select query itself needed to be changed. didn't the previous pagination code cause the correct page 2, 3, ... content to be queried for and displayed? the initial sql query used a variable named $initial_page. what is the code setting the value in that variable? when you integrated the code that i gave into your existing code, did you make sure that the $initial_page variable was producing the expected result? hint: i intentionally kept the name for the page value the same throughout the code, rather than to use two different names for it. you will need to go though the code and reconcile any variable name differences for that value.
-
you need to use oauth authentication. here's a phpmailer page - https://github.com/PHPMailer/PHPMailer/wiki/Using-Gmail-with-XOAUTH2
-
wouldn't that mean that you need to investigate why it isn't working in order to find and fix what's causing the incorrect operation?
-
if you are interested in displaying a range of links around the current page number (there's no guarantee the OP even saw the post suggesting that), here's some example code - <?php // build pagination links: prev, 1, range around current page, total_pages, next // number of +/- links around the current page number $range = 3; // number of items per page $limit = 12; // get total number of rows using a SELECT COUNT(*) ... query $total_rows = 3121; // calculate total number of pages $total_pages = ceil($total_rows / $limit); // get current page, default to page 1 $page = $_GET['page'] ?? 1; // limit page to be between 1 and $total_pages $page = max(1,min($total_pages,$page)); // produce array of pagination numbers: 1, range around current page, total_pages, without duplicates, between 1 and total_pages $links = array_filter(array_unique(array_merge([1],range($page-$range, $page+$range),[$total_pages])), function ($val) use ($total_pages) { return $val >= 1 && $val <= $total_pages; }); // build pagination links $pagination_links = ''; // get a copy of any existing get parameters $get = $_GET; // produce previous $get['page'] = $page - 1; $qs = http_build_query($get,'', '&'); $pagination_links .= $page == 1 ? 'prev ' : "<a href='?$qs'>prev</a> "; // produce numerical links foreach($links as $link) { $get['page'] = $link; $qs = http_build_query($get,'', '&'); $pagination_links .= $link == $page ? "$link " : "<a href='?$qs'>$link</a> "; } // produce next $get['page'] = $page + 1; $qs = http_build_query($get,'', '&'); $pagination_links .= $page == $total_pages ? 'next' : "<a href='?$qs'>next</a>"; // output pagination echo $pagination_links; note: your query to get the total number of rows should NOT select all the columns and all the rows of data. you should use a SELECT COUNT(*) ... query, then fetch the counted value.
-
if you are doing this for real, you would NOT actually update any values. you would just use a UNION query to calculate the current total, between the stock and the sales table, for each item_id you are interested in. actually using the oldest inventory first, is a fulfilment issue, not a stock/inventory quantity problem.
-
upgrading to php 8.1 on local computer
mac_gyver replied to webdeveloper123's topic in PHP Installation and Configuration
you don't have to add php to the windows path, unless you want to run the php Command Line Interpreter (CLI) anywhere outside of the folder the CLI is located in. if all you are doing is running the web server based installation of php, you don't have to set the windows path at all. you would have to set/change values within the web server configuration to use the correct php folder/version files. i would make a copy of all your document root files/folders, export all your databases to .sql files, remove the existing ampps installation, then install a free xAMP stack. -
the session variable is being used to determine which row of data to query for and use to populate the form field values with. you should also use the session variable to determine which row to update. your current method, of trying to use a get parameter in the form's action attribute (which contains a programming mistake anyways), will allow anyone to update anyone else's profile, since this value can be set to anything anyone wants, not just what you have attempted to set it to in the code. all external data submitted to your web pages can come from anywhere, can be set to anything, and cannot be trusted. also, your form processing code MUST trim, then validate all inputs before using them. had you done so, with the current attempted method of passing the id through the form's action attribute, your code would be producing an error for the user alerting them that there's no input id, and it would also be producing errors for the mismatch in form field names that @Barandhas pointed out, helping you to debug the mistakes in the code. here's an additional list of issues with the code - require isn't a function. the () around the filename are unnecessary clutter and should be removed. every redirect needs an exit/die statement after it to stop php code execution. a header() does not stop php code execution. all the code on that page is being executed every time the page gets requested. the code to retrieve the exiting data should come after the post method form processing code, should only be executed if the form has never been submitted, should keep the fetched data as an array, and should fetch the data into the same named variable that the post method form processing code is using (which should also be an array), so that after the form has been submitted, the form data will repopulate the form field values, so that the user doesn't need to keep reentering the changes over and over upon an error. if the query to get the existing data doesn't match a row, that's error and you should setup and display a message for the user alerting them to this problem, rather than to display a blank edit form. don't copy variables to other variables for nothing. this is just a waste of your time typing. the only time you should copy variables to other variables is when the meaning of the data in the variable has been altered, e.g. when trimming data, ... don't attempt to detect if the submit button is set. there are cases where it won't be. instead, detect if a post method form was submitted. if there can be more than one form processing code on a page, use a hidden field with a different value for each form, then use those values in the form processing code to control which code to execute. keep the form data as a set, in an array variable, then operate on elements in this array variable throughout the rest of the code. trim all the input data at once. since you will be keeping it in an array variable, you can do this will one single statement. validate all inputs, storing validation errors in an array, using the field name as the array index. after the end of the validation logic, if the array holding the user/validation errors is empty, use the submitted form data. because the update query can result in duplicate data (any column that must be unique should be defined as a unique index in the database table), you need error handling for that query that will test if a duplicate index error number has occurred, then setup a message for the user telling them what was wrong with the data that they submitted, so that they can correct the problem and resubmit the form. if there are errors at item #10, the code would continue on to display the html document, where you would test the array holding the errors and display its contents if there are, and redisplay the form, populating the form field values with the submitted form data. to get the form to submit to the same page it is on, simply leave the entire action='...' attribute out of the form tag. apply htmlentities() to any value you output on a web page to help prevent cross site scripting. don't write out code for every possible value. for the select/option choices and the radio buttons, define the choices in arrays, than loop over these defining arrays to produce the markup. you can also use these defining arrays in the validation logic to insure that only a permitted choice was made. the first select/option choice is usually an empty value with text that serves as a prompt to select one of the actual choices. this is actually need for the 'required' attribute to work, should the existing data being edited be empty or not match one of the permitted choices. this also results in an easily detected value for the server-side validation logic to test for. when you switch to use prepared queries, you would also want to switch to the much simpler PDO database extension.