-
Posts
5,449 -
Joined
-
Days Won
174
Everything posted by mac_gyver
-
the code you found on the Internet is so old and out of date that it won't even run under the latest php version. it also has a number of deficiencies, such as the login_success code won't prevent someone from accessing the protected page. you would be better off just writing your own login code from scratch, rather than to copy/paste something you found on the Internet.
-
how to add edit and delete options beside every result ?
mac_gyver replied to keloa's topic in PHP Coding Help
the point of programming help isn't to find or to write code for you. other than posting your current code and a statement of what you want, what have you tried? (hint: this is a common assignment and there are countless examples posted on the Internet that you could find and examine to see how others have done this.) -
the replies in this thread have already shown that there is no id value in the query statement. your form doesn't have an id field, but even more important, if you were passing the id through the form it would allow anyone to modify the user information for anyone else since you are not checking if the id being edited/submitted is the same as the currently logged in user. you must enforce security on the server in your php code. the only person who should be able to modify their own user information is the user who it belongs to (and perhaps moderators/administrators on your site.)
-
Segmentation faults are usually due to actual bugs in the underlying code or having a mix of different versions of php core files and extensions (i.e. not all built with the same c header files.) is there any additional information in the web server's error log file? you can check the php bug reports to see if anyone else is having the same problem and/or make a bug report if you feel this is something due to the underlying php code. (php 5.5.6 just fixed a segfault if the PDO constructor throws an exception, perhaps this is related to that.) the only thing i can suggest you can try in the code would be to put a try/catch block around the foreach(){} block in case the query statement is failing and throwing an uncaught exception. temporarily turning off the PDO::ERRMODE_EXCEPTION may help pin point the issue (if its an actual bug in php.)
-
a) what URL are you using in your browser's address bar to request the main page? it should be http://localhost/your_main_file_name.php b) partly related to the above, what extension does your file have, this must be .php c) what opening php tags are you using? using full <?php tags will always work, short ones <? not so much. d) partly related to the above, what does the 'view source' in your browser of your page containing php code look like?
-
i recommend that you first get the datatables example to work using PDO so that you will become familiar with what the server-side code is doing, then all you will need to basically do is to alter the query section in it to use your SELECT ... FROM ... JOIN terms. the example code is responsible for producing the WHERE, ORDER BY, and LIMIT terms based on the values sent from the javascript/ajax. it's unfortunate that the author of the server-side example didn't abstract the database statements so that switching to a different driver wouldn't be that hard. however, based on your previous thread, i went through the datatables server-side example and modified the server_processing.php code so that it would make use of a database wrapper. the following is the datatables example server_processing.php code and a minimal mysqli wrapper class (you would need to write/modify the wrapper class to use PDO statements) - server_processing.php <?php include 'db.mysqli.class.php'; //include 'db.sqlite3.class.php'; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Easy set variables */ /* Array of database columns which should be read and sent back to DataTables. Use a space where * you want to insert a non-database field (for example a counter or static image) */ $aColumns = array( 'engine', 'browser', 'platform', 'version', 'grade' ); /* Indexed column (used for fast and accurate table cardinality) */ $sIndexColumn = "id"; /* DB table to use */ $sTable = "ajax"; /* Database connection information */ $gaSql['user'] = ""; $gaSql['password'] = ""; $gaSql['db'] = ""; $gaSql['server'] = ""; //$gaSql['db'] = "{$_SERVER['DOCUMENT_ROOT']}/test1.sqlite"; // path/filename for sqlite db file /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * If you just want to use the basic configuration for DataTables with PHP server-side, there is * no need to edit below this line */ /* * Local functions */ function fatal_error ( $sErrorMessage = '' ) { header( $_SERVER['SERVER_PROTOCOL'] .' 500 Internal Server Error' ); die( $sErrorMessage ); } /* * database connection */ $gaSql['link'] = new db(); // instance of db wrapper if ( ! $gaSql['link']->connect( $gaSql['server'], $gaSql['user'], $gaSql['password'] ) ) { fatal_error( 'Could not open connection to server' ); } if ( ! $gaSql['link']->select_db( $gaSql['db'] ) ) { fatal_error( 'Could not select database ' ); } /* * Paging */ $sLimit = ""; if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' ) { $sLimit = "LIMIT ".intval( $_GET['iDisplayStart'] ).", ". intval( $_GET['iDisplayLength'] ); } /* * Ordering */ $sOrder = ""; if ( isset( $_GET['iSortCol_0'] ) ) { $sOrder = "ORDER BY "; for ( $i=0 ; $i<intval( $_GET['iSortingCols'] ) ; $i++ ) { if ( $_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true" ) { $sOrder .= "`".$aColumns[ intval( $_GET['iSortCol_'.$i] ) ]."` ". ($_GET['sSortDir_'.$i]==='asc' ? 'asc' : 'desc') .", "; } } $sOrder = substr_replace( $sOrder, "", -2 ); if ( $sOrder == "ORDER BY" ) { $sOrder = ""; } } /* * Filtering * NOTE this does not match the built-in DataTables filtering which does it * word by word on any field. It's possible to do here, but concerned about efficiency * on very large tables, and MySQL's regex functionality is very limited */ $sWhere = ""; if ( isset($_GET['sSearch']) && $_GET['sSearch'] != "" ) { $sWhere = "WHERE ("; for ( $i=0 ; $i<count($aColumns) ; $i++ ) { if ( isset($_GET['bSearchable_'.$i]) && $_GET['bSearchable_'.$i] == "true" ) { $sWhere .= "`".$aColumns[$i]."` LIKE '%".$gaSql['link']->escape( $_GET['sSearch'] )."%' OR "; } } $sWhere = substr_replace( $sWhere, "", -3 ); $sWhere .= ')'; } /* Individual column filtering */ for ( $i=0 ; $i<count($aColumns) ; $i++ ) { if ( isset($_GET['bSearchable_'.$i]) && $_GET['bSearchable_'.$i] == "true" && $_GET['sSearch_'.$i] != '' ) { if ( $sWhere == "" ) { $sWhere = "WHERE "; } else { $sWhere .= " AND "; } $sWhere .= "`".$aColumns[$i]."` LIKE '%".$gaSql['link']->escape($_GET['sSearch_'.$i])."%' "; } } /* * SQL queries * Get data to display */ // sqlite does not support SQL_CALC_FOUND_ROWS, removed from query - // SELECT SQL_CALC_FOUND_ROWS `".str_replace(" , ", " ", implode("`, `", $aColumns))."` $sQuery = " SELECT `".str_replace(" , ", " ", implode("`, `", $aColumns))."` FROM $sTable $sWhere $sOrder $sLimit "; $rResult = $gaSql['link']->query( $sQuery ) or fatal_error( 'Database Error: ' . $gaSql['link']->errno() ); /* Data set length after filtering */ //sqlite does not support SQL_CALC_FOUND_ROWS, changed query to COUNT() with same where clause as above // $sQuery = " //SELECT FOUND_ROWS() //"; $sQuery = " SELECT COUNT(`".$sIndexColumn."`) FROM $sTable $sWhere "; $rResultFilterTotal = $gaSql['link']->query( $sQuery ) or fatal_error( 'Database Error: ' . $gaSql['link']->errno() ); $aResultFilterTotal = $rResultFilterTotal->fetch_array(); $iFilteredTotal = $aResultFilterTotal[0]; /* Total data set length */ $sQuery = " SELECT COUNT(`".$sIndexColumn."`) FROM $sTable "; $rResultTotal = $gaSql['link']->query( $sQuery ) or fatal_error( 'Database Error: ' . $gaSql['link']->errno() ); $aResultTotal = $rResultTotal->fetch_array(); $iTotal = $aResultTotal[0]; /* * Output */ $output = array( "sEcho" => intval($_GET['sEcho']), "iTotalRecords" => $iTotal, "iTotalDisplayRecords" => $iFilteredTotal, "aaData" => array() ); while ( $aRow = $rResult->fetch_array() ) { $row = array(); for ( $i=0 ; $i<count($aColumns) ; $i++ ) { if ( $aColumns[$i] == "version" ) { /* Special output formatting for 'version' column */ $row[] = ($aRow[ $aColumns[$i] ]=="0") ? '-' : $aRow[ $aColumns[$i] ]; } else if ( $aColumns[$i] != ' ' ) { /* General output */ $row[] = $aRow[ $aColumns[$i] ]; } } $output['aaData'][] = $row; } echo json_encode( $output ); ?> db.mysqli.class.php <?php // minimal mysqli db wrapper class to support the jquery datatables server side example // result class class db_result{ private $resource; public function __construct($resource){ $this->resource = $resource; } public function fetch_array(){ return $this->resource->fetch_array(); } } // db wrapper class using mysqli class db { private $db; // instance of the actual database class private $errno; // last error number private $error; // last error message public function __construct(){ // do nothing } public function connect($host,$user,$pwd){ $result = $this->db = mysqli_connect($host, $user, $pwd ); $this->errno = $this->db->errno; $this->error = $this->db->error; return $result; } public function select_db($db){ $result = $this->db->select_db($db); $this->errno = $this->db->errno; $this->error = $this->db->error; return $result; } public function query($query){ // result set type of query $result = $this->db->query($query); $this->errno = $this->db->errno; $this->error = $this->db->error; if($result){ // query ran return new db_result($result); } else { // query failed return $result; } } public function escape($string){ return $this->db->real_escape_string($string); } public function errno(){ // provide get method to permit all method access - $db->errno() return $this->errno; } public function error(){ return $this->error; } } ?>
-
did you even try to do this? all you have posted is your existing code and that you want to change it to use the server side datatables. where exactly are you stuck at?
-
in case you revisit this thread, i looked at your actual code more and there's one bug and some code that isn't doing what you think. the bug: if someone does submit a value with a < or a > in front of it, you have logic to check for that and produce the $value without the < or > character. that $value is what you need to supply to the actual query. your current code uses the raw $_GET value and it still has the < or > character and if the query runs isn't going to produce the result you expect. the loop where you are checking for the < or > characters is where you should store the $value into the $params array. this will also eliminate the need for the lines of code later that are setting $params to the array of $_GET variables and using array_filter() and array_values() on it. the code not doing what you think: by definition all $_GET variables are a string data type, no matter what the value in them is. the code using is_string(), is_int(), and is_float() is checking the type of variable, not what's in it and if you look at your $types value it will always be 'ssssss'. this will actually produce a query that works, but is not what you intend. the same loop mentioned above could be used to build the $types string, just add statements to the switch/case logic for each possible choice to add the appropriate type character to the $types variable. this will also eliminate the need for the foreach() loop building the $types value later in the code. lastly, variable variables are messy and usually not needed. the following - for ($i=0; $i<count($params);$i++) { $bind_name = 'bind' . $i; $bind_name = $params[$i]; $bind_names[] = &$bind_name; } can be replaced by - for ($i=0; $i<count($params);$i++) { $bind_names[] = &$params[$i]; // use the $params data array directly }
-
How did user bypass select option in my site's item entry?
mac_gyver replied to floridaflatlander's topic in PHP Coding Help
all external data can be anything that someone or a bot script chooses to submit, cannot be trusted, and must be validated to insure it is an expected value or within an expected range of values. someone or a bot script doesn't need your form at all in order to submit data to your form processing code. -
i see that 4-5 interested people have downloaded your files, but no replies yet. the reason for this is programming and troubleshooting programming is an exact science and since you haven't provided any information about - no one here can really help you with those problems.
-
the array causing the initial(ization) problem is $bind_names[]. it is loaded with values in the main code, then added to in the included file. you need to add $bind_names = array(); before the usage in the included file. as a side note, if/once this code is inside a function/method, the problem would not exist because each call of the function/method would recreate the array/destroy it when the function/method call ends and the database error would never have occurred.
-
@JIXO, if you are saving/serving the file in/from a database, you most certainly would need to escape the binary file data before putting it into a query statement and you would most certainly need to echo the contents of the file to output it to the browser after sending the appropriate headers.
-
care to share what those problems are? we are not standing right next to you, nor do we have the ability to run your code because we don't have your database tables, nor do we even know what size file you tried.
-
you may have seen this mentioned before, but just telling a help forum that something doesn't work is pointless. we are not standing right next to you and don't know what your code did do that leads you to believe it didn't work. you must communicate exactly what it do and at what point it did it. what exactly did you do and what did you see in front of you after you did it?
-
without a specific question (one at a time) or a statement of what sort of problem or error you are having with your code, it's not directly possible to help you. just posting what you want to do and dumping 350+ lines of your code on a forum (that we cannot easily run because we don't have your tables or data) doesn't tell use where you are stuck at in doing this, so we have no clue what to help you with.
-
How do I get database values for currently logged in users?
mac_gyver replied to DeX's topic in PHP Coding Help
how could a user set a session variable? that's completely under the control of your code. -
More questions regarding sending emails from a webpage.
mac_gyver replied to njdubois's topic in PHP Coding Help
for the DNS zone records, those are yours to setup and they are specific to your domain name (though your web host should probably have macro's setup so that any time a domain is added it creates records for that domain.) the gist of this is even through you are using your web host's shared mail server, you set up DNS zone records that treat it as though it is your own mail server, so that anyone/anything looking at it from the outside thinks it is your own dedicated mail server. -
More questions regarding sending emails from a webpage.
mac_gyver replied to njdubois's topic in PHP Coding Help
three of the most common problems with emails being 'dropped' are - 1) setting the From: header in the email to be that of the recipient, not of the sender, which is YOUR sending mail server 2) by not having appropriate DNS zone records at your sending mail server that allow the receiving mail servers to determine that the email is authorized to be sent by your sending mail server 3) your mail server has been flagged as sending spam and you would need to have it white-listed at the specific receiving mail servers. for the case of the From: header, if the domain in the from address is the same as the receiving mail server, the receiving mail server KNOWS it didn't send that email to itself and so it simply discards it. the email address in the From: header must at least have a domain that corresponds to your sending mail server. for the case of the DNS records, you generally need MX, A, SPF (Sender Policy Framework), and reverse lookup records at your sending mail server so that the receiving mail server can check that the mail server that is trying to send to it corresponds to where the email says it is coming from. most of the major ISP's have a 'postmaster' FAQ that lists the things they check and what their white-list procedure is. once you get your email to work for one of the more stringent ISP's, it should work with most of them. -
your main logic could/should look like this pseudo code/outline - $expected = array('location' => 'text', 'type' => 'text', 'beds' => 'text', 'price' => 'text', 'nbuild' => 'int', 'resale' => 'int', 'coastal' => 'int', 'seaview' => 'int', 'rural' => 'int', 'golf' => 'int', 'ppool' => 'int', 'comp' => 'int', 'garden' => 'int', 'terrace' => 'int', 'aircon' => 'int', 'heating' => 'int', 'garage' => 'int', 'telephone' => 'int', 'furnished' => 'int', 'internet' => 'int', 'dpaid' => 'int', 'propid' => 'text'); define('SHOWMAX', 10); // common parts of the query $from_term = "FROM detailstable JOIN newloctable ON detailstable.location=newloctable.newlocid JOIN typetable ON detailstable.type=typetable.typeid JOIN pricetable ON detailstable.price=pricetable.priceid JOIN bedtable ON detailstable.beds=bedtable.bedid JOIN photossale ON detailstable.detailsid=photossale.propsaleid"; $select_term = "DISTINCT detailsid, trueprice, reduced, offers, `desc`, `propid`, `bathrooms`, `location`, `type`, `price`, `beds`, photossale.photo1, newloctable.newloc, typetable.style, bedtable.`number`"; $order_by_term = "ORDER BY ABS(detailstable.trueprice), bedtable.number, detailstable.propid ASC"; // build the specific where term $where_term = build_where_term($expected); // assuming your code to do this is in a function // first try the specific where term $query = "SELECT COUNT(*) as total $from_term $where_term"; // you would need to dynamically build the $types and $input_data to go with the $query statement here... // run the query and use the result (this count query will return exactly one row) $result = $conn->prepared_query($query,$types,$input_data); // assuming a class method to do this // get the count of matching rows $totalRecords = $result[0]['total']; if($totalRecords == 0) { // the specific query did not match any rows, use the general query $expected = array('location' => 'text', 'type' => 'text', 'beds' => 'text', 'price' => 'text', 'dpaid' => 'int', 'propid' => 'text'); // build the general where term $where_term = build_where_term($expected); // assuming your code to do this is in a function $query = "SELECT COUNT(*) as total $from_term $where_term"; // you would need to dynamically build the $types and $input_data to go with the $query statement here... // run the query and use the result (this count query will return exactly one row) $result = $conn->prepared_query($query,$types,$input_data); // assuming a class method to do this // get the count of matching rows $totalRecords = $result[0]['total']; } // at this point, $totalRecords indicates if there are any rows, from either the first specific query or the second general query // if there are any records, the $where_term is the appropriate value to use in the data retrieval query if($totalRecords == 0) { // there are no results to display echo 'sorry, no match for the input values'; } else { // there are results to display // produce the limit term $startRow = $curPage * SHOWMAX; $limit_term = "LIMIT $startRow," . SHOWMAX; // this single data retrieval query will receive the appropriate $where_term from the above logic $query = "SELECT $select_term $from_term $where_term $order_by_term $limit_term"; // you would need to dynamically build the $types and $input_data to go with the $query statement here... // run the query and use the result (this query can return any number of rows) $result = $conn->prepared_query($query,$types,$input_data); // assuming a class method to do this // use result from data retrieval query }
-
this is indicative of an initialization problem. most likely your array used for the dynamic binding is being added to, rather than starting over, by the set of queries in the included file and the execute() statement is failing (you are not checking if the execute() actually ran) because the number of parameters in the query no longer matches the number of bind parameters. 1) you should ALWAYS check if a statement has failed or not before trying to use the result from that statement, in this case the execute() statement. 2) you should ALWAYS declare/initialize array variables before populating them in a loop. also, you have a bunch of repetitive code, taking up your time typing or copy/pasting/changing it and frankly reducing the chance of someone in a help forum even looking at it. each pair of related queries, the COUNT() query and the data retrieval query are very similar, but you have repeated line after line of code to build both of them, then repeated the code again in the included file. other than the COUNT() term or the list of SELECTed fields and the LIMIT clause they are the same (actually the count query doesn't need the ORDER BY term.) build the parts of the query separately, once, then form the two queries using the appropriate parts. some of these parts, like the list of selected fields, the FROM ... JOIN term, and even the LIMIT x,y term are the same for the main queries and the included queries and could be reused. to build the COUNT() query, you would just use - $query = "SELECT COUNT(*) $from_term $where_term"; to build the data retrieval query - $query = "SELECT $select_term $from_term $where_term $order_by_term $limit_term"; next, the two queries in the included file only differs from these two queries in the where term. the only code you need to run again is the code using your $expected array to build the where term. this code should be in a function that accepts the appropriate $expected array as an input parameter and returns the produced where term. lastly, you are repeating the code that actually prepares and runs the query at least 4 times. you should move toward making a function or an OOP class (you can actually extend the mysqli class to add a 'prepared_query' function.) this code would accept the query statement, the input bind type list (the 'ssis...'), and an array of input variables to bind), prepare the query, bind the input variables, execute the query, bind any result variables, fetch and return the data (all with some error checking logic for each step that can fail.) you would just call this function/class method each time you need to run a query, rather than repeating the code over an over. by moving code into functions/classes and reusing the common parts of the queries, your main logic would be greatly simplified.
-
is there some reason you have both mysqli and mysql statements in your code? whatever connection type you have is the type of statements you must use.
-
since your error message is still for an old mysql_ function, you either didn't save the changes to the file or the error is from some other line in your code.
-
posting one line of your code doesn't help anyone to help you. i could name 10-20 different reasons why the one line of code you have posted doesn't show anything. if you want actual help with your code, you will need to post all the relevant code needed to reproduce the problem.
-
the field name and sort direction being put into your existing query would instead be variables who's value comes from the links. to prevent sql injection you must either use a level of abstraction (use just a number in the links that is associated with each column name, then map the submitted number to the actual column name in your php code - an array with the index/value would work) or you must validate that the submitted column name is only just a permitted column name without anything else being part of it (an in_array() statement would work.)
-
rather than showing what you tried, show some sample data, for at least two different des group values, and what result you want from that data.