-
Posts
5,518 -
Joined
-
Days Won
187
Everything posted by mac_gyver
-
the most likely reason for the random failures of the code is probably due to different browsers handling markup errors differently. the html in the pages being produced needs to be valid to have a chance at working the same in all browsers/browser-versions. what a mess. this code is long over due to be written from scratch, using general, data driven, DRY, programming. there's a ton of hard-coding (i even saw a 2015 year being used in a path that would need to be manually changed each new year, and i'm guessing this is what the 11 in the file names are there for, to distinguish different hard-coded instances of the site) and repetition of form/form-processing code between main and included files. of the 6800+ lines present in the .zip, there's probably only about 2000 lines needed to do this task.
-
see the following example code that shows several of these suggestions - <?php include "dbinfo.php"; // do this once, since both your form and form processing code needs a db connection // the defined constants DB_NAME, DB_USER, DB_PASS, and DB_HOST would be defined in your dbinfo.php file $pdo = new pdo("mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=utf8",DB_USER,DB_PASS); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); // form processing code - if(isset($_POST['update'])) { echo '<pre>',print_r($_POST,true),'</pre>'; // examine what the submitted form data is // i'll leave it up to you to work on the form processing code } // members table - id, member (i'm going to assume this is a something like a username or should it be the member's/user's firstname/lastname) // divisions table - id, name, image // member_div table - member_id, division_id $id=$_GET['id']; // the member to show the data for // one JOIN'ed query that gets the data you want in the order that you want it $query = " SELECT d.id div_id, d.name div_name, d.image div_image, m.username, m.id user_id, md.member_id IS NOT NULL AS checked FROM divisions d JOIN members m LEFT JOIN member_div md ON d.id = md.division_id AND m.id = md.member_id WHERE m.id = ? ORDER BY div_name "; $stmt = $pdo->prepare($query); // prepare the query $stmt->bindvalue(1,$id); // bind the input data to the place-holder $stmt->execute(); // run the query $result = $stmt->fetchall(); // fetch all the rows. this will be an empty array if the query didn't match any row(s) // produce the output from the $result array of data from the database query if(empty($result)){ echo 'There is no data to display'; // this won't occur unless there is no divisions and members data. } else { // there is data to display $record = $result[0]; // make a copy of the first row for the heading information ?> <h3>Updating divisions for member: <?php echo $record['username'];?></h3> user's id: <?php echo $record['user_id'];?> <br> <form method="post" > <table width="60%" border="1" align="left"> <th width="5%">id</th><th width="45%">division</th><th width="45%">image</th><th width="5%">status</th> <?php foreach($result as $row) { echo "<tr><td>{$row['div_id']}</td>"; echo "<td>{$row['div_name']}</td>"; echo "<td>{$row['div_image']}</td>"; $chk = $row['checked'] ? 'checked' : ''; // produce the checked state for each checkbox echo "<td><input type='checkbox' name='chk[{$row['div_id']}]' $chk /></td>"; echo "</tr>\n"; } ?> </table> <input name="update" type="submit" value="Update"> </form> <?php } ?> note: the db column names in this example may not match your's and would need to be modified to run at all.
-
checked check-boxes will be set in the submitted form data. unchecked check-boxes won't be present in the submitted form data. therefore, the value isn't really important and can be left out of the code. it's easy to detect what check-boxes are checked, but you must also be able to remove the stored data for check-boxes that go from checked to not checked. the easiest way to do this is to just remove all the relevant data and then set/insert the data for the checked check-boxes. your code also isn't using the id='....' attribute, so don't produce that in your code unless you need it. your checkbox name='....' attribute should be an array name with the array key/index being the division id value. this will give you a php array from the submitted form data with the division id values that were checked. the line in your code would look like - echo '<td><input type="checkbox" name="chkbox['.$record2['id'].']" /></td>'; your members table should just hold the unique information about each member. it should not hold this division data. you actually need a 3rd table to hold this data, with one row for each piece of data, with member_id, and division_id columns. the member_id and division_id columns need to be set up with a unique composite index to enforce unique data pairs. to retrieve the data to display it, you should use one JOINed query, then just loop over the data and output it the way you want. now the bad news - the mysql_ database library of functions are obsolete and will be removed from php in the near future. you need to learn and use either the PDO (the best choice) or the mysqli_ library of functions so that you are learning current technology. you also need to properly treat external data being put into sql query statements. the best way of doing this is to use prepared queries, with place-holders/bound data in the sql statement for the data values. both the PDO and mysqli_ libraries support prepared queries, but PDO is easier and more consistent to use. P.S. $_PHP_SELF is also obsolete (and i'm pretty sure that's got an extra _ in it) and should not be used. for html5, you can just leave the action='...' attribute out of the <form....> tag or you can use action='#'
-
if your server is set up correctly, and if it's not, you can fix to be so, $_SERVER['DOCUMENT_ROOT'] refers to the document root folder and can be used for building an absolute file system path for include/require statements.
-
@sigmahokies, the php programming help forum section is for asking for help with code you have written. it is not for asking how you can learn something or for links to sites, because we don't know the complete requirements for what you are looking for. this is not a suggestion for you to try and list all the requirements that you are looking for. it's a suggestion that it's up to you to do the research for the information that you want to know, not to ask others to do this for you, because you are the only one here that knows what exactly you are looking for and at what level of detail that matches your programming knowledge and experience. if you have specific questions about how you would design something, you can post them in the Application Design forum section, but please read the rules/stick-posts for that forum section, it is not to get someone to completely do your design for you, just to answer specific questions you have while you are doing the design - see the sticky/pinned post http://forums.phpfre...ication-design/
-
i recommend using a 'template' method, where the first instance of your form field(s) is(are) inside of a <div></div> container and become a source template that you use when appending the dynamically added form fields. this eliminates the need to duplicate the markup for the form fields in both the html and in the javascript, i.e. DRY (Don't Repeat Yourself) programming. next, you need to use an array name for your form fields. this eliminates the need to maintain a counter in the javascript code and allows you to use php's array functions to loop over the submitted data. see the following example - <script type="text/javascript"> function addField() { // create an empty div element var div1 = document.createElement('div'); // get the template html and put it into the empty div div1.innerHTML = document.getElementById('template').innerHTML + "<input type='button' onClick='removeField(this)' value='-'>"; // append the new div to the target area on the page document.getElementById('add_here').appendChild(div1); } function removeField(div){ document.getElementById('add_here').removeChild(div.parentNode); } </script> <body> <form method='post' action='formaction.php'> Children <!-- Template. This first instance of "whatever" will be appended in the add_here div --> <div id="template"> <input type="text" name="child[]" placeholder="Child's Name" style="width:250px; margin-left:7px; margin-right:4px;"> <input type="text" name="title[]" placeholder="Title" style="width:250px; margin-left:7px; margin-right:4px;"> <input type="button" onClick="addField()" value="+"> </div> <!-- container to hold the dynamically added instances of "whatever" --> <div id="add_here"> </div> <input type='submit'> </form>
-
a unix timestamp would be stored as an integer data type. the functions used to produce the integer value would be those that produce a unix timestamp, such as php's time()/mktime()/strtotime() functions or mysql's UNIX_TIMESTAMP() function. a mysql timetamp would be defined as a mysql timestamp data type, with the values being supplied to it as either a 'YYYY-MM-DD HH:MM:SS' string or a YYYYMMDDHHMMSS number.
-
yes, but what does happen? we are not sitting there with you and don't know what you saw. what did happen, even if nothing happened, and what did you expect to happened?
-
What is the best method to write long if - else conditions?
mac_gyver replied to thara's topic in PHP Coding Help
if you find yourself editing your program logic, just to add, remove, or change values that determine what the logic does, you need to use a data driven design. after your write and test your program logic, you shouldn't be touching the code unless you are adding or changing the features in the code. using the general purpose method 02, in order to change the set-point values, add or remove the quantity of settings, or reuse the program logic (which should be a function/class-method) for a different set/purpose of mapping values, all you have to do is change or supply a different data definition. the data definition(s) can also then be stored in a database where an administrator interface can be provided to easily define/edit the definition(s). -
is your database holding a UNIX Timestamp or a MYSQL Timestamp, they are not the same things (though a MYSQL Timestamp is internally stored as a unix timestamp and has the same range restrictions.) a UNIX Timestamp is an integer that represents the number of seconds since '1970-01-01 00:00:00' UTC. a MYSQL Timestamp is formatted/treated as either a 'YYYY-MM-DD HH:MM:SS' string or a YYYYMMDDHHMMSS number. any mysql or php functions that operate on your data would need to be specific to what your data type actually is. are you using a UNIX Timestamp/integer or you are using a MYSQL Timestamp data type?
-
i looked at your CLASS code closer (i initially misread the $session_uname|$f_uname) and doing that won't do what you think. that's producing the bitwise OR between those two values, in the php code. i suspect you want a logical OR in the sql query statement, which would require sql syntax to do that. you cannot bind sql syntax, only values. you would need to form the correct sql syntax, with place-holders for EACH value, then bind each value. also, using the same place-holder name more than once is not proper usage. it does work with emulated prepared statements, but this is likely a bug that could get fixed at any time and you shouldn't rely on it in your code.
-
your program logic makes no sense. you are looping over the first query result to just get the id values, looping over any results from the second query for each id, then at the end looping over the first query result again. you are also building the output in variables but you are re-assigning the variable, rather than concatenating to it, on each pass through the loops. do what i suggested and run one JOINed query to get the data you want. you will have just one loop and a minimum of code to produce the output.
-
is the query giving you one row, which is what a count(*) will do since there's no GROUP BY in the query, with the COUNT(*) value in the row being a zero, or is the COUNT(*) value in the row a 1?
-
that would indicate that $context doesn't contain what you expect. what does adding var_dump($context);, right before the call to the function show?
-
are you sure the code is running at all? are you getting any output on the page (a blank .php page is usually due to a fatal parse or runtime error.) what is the actual value in $context['user']['mentions'] at the point where you are calling the function?
-
are you calling the function? a function consists of two parts - 1) the definition, which starts with the 'function' keyword, and 2) calling the function at the point in your code where you want to make use of what the function does. next, the input parameter(s) to the function should be the actual value that the function expects, so that the function is general purpose, and can be called with the input coming from any source. this function is testing if the input parameter is a number greater than zero. the input parameter should just be the number, without any context about where it is coming from. it's your calling code that knows the context of where the value is coming from. use the following for the first few lines of your function definition - function growl_notification($num) { if ($num > 0) and use this where you are calling the function - growl_notification($context['user']['mentions']);
-
even if you use a SELECT query to get the initial value, only use this for display purposes. any updating of the value should be done in a single query, so that you don't loose data when there are multiple concurrent instances of your code running, each trying to modify the value. or better yet, don't maintain a count/accumulator in a table column. instead, insert a separate row into a database table for each transaction that modifies a value, then sum up the values from the rows to get the current total. this will give you an audit trail so that you can detect things like double-page requests, programming errors, or if someone manages to find a security hole in your code and submits an arbitrary data value that modifies the count/accumulator by more than you want.
-
your two class methods will return an array. it's an empty array if the query didn't match any rows or it's an array of the all the rows the query did match, assuming that you are still throwing exceptions for any errors. all your for(){} and while(){} loop logic, besides not working, is not necessary. you can test if the returned array is empty or not using, well, empty(). you can loop over the arrays using a foreach(){} loop. next, $status_replies_=$project->reply2StatusView($id[$i]); you are running a select query inside of a loop. this is a performance killer due to the round-trip communication it adds between php and the mysql server. for what you are doing, you should run one JOINed query to get the data that you want, then just loop over that data. edit: public function statusView($session_uname,$f_uname) { you are passing an array and an index into your function/method to supply an account name. this is not how to write general purpose code. the function/method expects an account name as in input, that's all you should supply as an input parameter, so that you can reuse the function/method regardless of where the input comes from. the definition should just be - public function statusView($account_name) {. the code inside the function should just use $account_name, and the calling code would be - $status2view=$project->statusView($session_uname[$f_uname]); // supply the account name input, from wherever it is stored
-
a) are you running the query directly against your database using a query browser of some kind so that you would be seeing any errors from the query? b) what i posted isn't a copy/paste query. you need to adapt it to use your table and column names. you would also need to add in the active=1 logic.
-
see this link - http://dev.mysql.com/doc/refman/5.6/en/example-maximum-column-group-row.html where what you are doing is getting the maximum note id per group. using the last method shown at that link (left join) the following works (cannot vouch for how efficient it is, but it is fairly easy to understand or modify to use any JOINed table query for the two sub-queries) - SELECT t1.* FROM (SELECT p.*, n.note_id, n.comment FROM prospects p LEFT JOIN notes n ON p.id = n.prospect_id) t1 LEFT JOIN (SELECT p.id, n.note_id FROM prospects p LEFT JOIN notes n ON p.id = n.prospect_id) t2 ON t1.id = t2.id AND t1.note_id < t2.note_id WHERE t2.id IS NULL; this is using simplified table naming with - a `prospects` table with at least an `id` column and a `notes` table with at least `note_id`, `prospect_id`, and `comment` columns.
-
one would hope that the recaptcha api would return a unique error for each different thing that could go wrong, but perhaps not. the ip address in the data to the api is optional, so if it's not being put into the data, it doesn't matter, but what if it is present and it's not the same value from the client when the client solved the captcha? if the client being used for testing is on the same local network with the server, the ip address that the server gets in $_SERVER['REMOTE_ADDR'] will be a local ip. the ip address that the recaptcha api saw when the captcha was solved would be the public network ip address. try removing the ip key/value pair from the $captcha_params. next, i wonder what happens if you submit the same curl request twice, which would happen if your .php page is being requested twice? a lot of clients request a page twice. perhaps the output being seen is that due to a second request, and since the recaptcha api has already seen and responded to any specific 'g-recaptcha-response' value, perhaps it returns a null in this case? i would add code in your .php page that logs some information (see file_put_contents() with the FILE_APPEND flag) from the client request and from the curl response each time it runs. this will let you see if there are multiple requests being made for each form submission and if the curl response is always the same. you can also try using an 'official' recaptcha php class (there's a link on the recaptcha/google page.) perhaps it is setting curl options that can have an affect (i saw some code that's setting an ssl verify host parameter to a false value.) however, getting a null from a curl request seems more like a communication problem. the url that's being used would require that the server have open_ssl installed. what does the output from a phpinfo() statement show for the SSL entry under the CURL section?
-
without an ORDER BY term in your sql statement, there is NO guarantee that any particular row of matching data is going to always be the first row. what characteristic does your data have that identifies what order you want the rows from the query to be in and what identifying characteristic or value is there that you can use to not include the one particular row in the result set?
-
just because the mail() function is returning a true value, doesn't mean that the sending mail server has sent or has any intention of sending the email. some mail servers are configured to return a true value/no errors to php regardless of what happens to the email so as to not allow hackers to use the returned errors to find mail box names... next, the yahoo/protonmail email servers may be doing a more thorough check of the DNS records at your web hosting than what gmail is doing (any chance you are using google web hosting so that sending an email to gmail is coming from a google server and the sending mail server is the same as the receiving mail server?). the ONLY information a receiving mail server gets with any email is the ip address of the server/device the email is being sent from (from the tcp/ip data packets) and information in the email, i.e. the from address. the receiving mail server will use these two pieces of information to try and validate that the email is actually coming from where it says it is by checking the DNS records at the sending ip address and at the domain in the from address. perhaps the yahoo/protonmail mail servers are looking for a secondary piece of information that gmail isn't and something is either missing (missing values usually aren't a problem) or is set incorrectly (incorrect values will get an email discarded.) at a minimum, there should be an SPF DNS zone record at the domain being used in the from: mail header that indicates the sending mail server is authorized to send email for that domain. you can check your DNS records and test your sending mail server for configuration problems at a site like dnsstuff.com edit: if this is for a contact form, where you will always be sending to a single email address, you can use SMTP authentication (i.e. provide the access password for the mail box) against a receiving email address and send the emails directly to the mail server where the email address is hosted at. to use SMTP authentication, you will need to exchange smtp commands with the mail server. the phpmailer/swiftmailer classes handle this for you.
-
is your code producing any php errors or any oci errors? is your code producing a completely blank page or does anything on the page get output to the browser and its just the query result that doesn't get output? if you read any of the 'help my page/query doesn't produce any output' posts on any of the php programming help forums, you will notice a common thread, displaying php errors and testing for and displaying database statement errors. you must ALWAYS have php's error_reporting set to E_ALL and for development/debugging display_errors should be set to ON. these two settings should be in the php.ini on your development system, so that they will report php parse/syntax errors and so that you don't need to remember to put them into the code you are developing/debugging. all the database statements that can fail due to an error (connection, prepare/parse, query/execute) must ALWAYS test for errors and handle them in a meaningful way. for development/debugging, you would want to display the database error information. next, queries that run successful can still match zero rows and in most cases you should use your database's num_rows function/method (see oci_num_rows()) to test for and handle this case. if your code was already was doing these things, it (your code) would be telling you if, where, and way it is failing.