Jump to content

mac_gyver

Staff Alumni
  • Posts

    5566
  • Joined

  • Days Won

    200

Everything posted by mac_gyver

  1. your php code contains a number of syntax/parse errors, some incorrect array references, and wrong usage of mysqli_query statement. you need to have php's error_reporting set to E_ALL and display_errors set to ON in the php.ini on your development system to get php to report and display all the errors it detects. due to the syntax/parse errors in your main file, these two settings cannot be set in your main code because your main code never runs for this type of error. the string concatenation you are doing inside the while(){} loop is where most of the problems are. you are missing some concatenation dots OR you should just put everything inside of a php double-quoted string and forget about concatenation. you also need to specify the array name inside that same code. all the array references need to have $row as part of them. the php errors, after you turn them on, should help you find the remaining problems in the code.
  2. if you are going to take the time to learn a new php database extension, use that time learning the PDO extension. it's more constant, simpler, and cleaner than the mysqli extension, particularly when using prepared queries.
  3. phpmailer should (according to the documentation) work for any php 5+ version (5.4+ if you are using oauth.) however, assuming you are using the latest version of php mailer, that particular section of code IS using php syntax that was introduced in php 5.3 and will throw a parse/syntax error for lower versions. the php version check logic they put in that particular code doesn't have any affect because the code never runs when there is a syntax error. you can edit the section of code for the clearQueuedAddresses method so that it only contains the first set of conditional logic. you could also put the section of code that's in the else{} conditional statement, that's using the php5.3+ syntax, into an external file and require it in place of the in-line code. the require statement will only be executed if the else{} condition is true and this won't throw a parse/syntax error since the code in the required file is only evaluated when the require statement is executed. you can also (at your own risk) download and use older versions of php mailer - https://github.com/PHPMailer/PHPMailer/releases
  4. probably not. there's two problems with this. 1) no one is likely to want to go through 40 or 6 * 40, depending on what your statement about what you are doing means, different select/option menus (there's probably a better interface to do this), and 2) this shows that your database table has designed badly. so, what does this data actually represent and how many select/option menus are there in each form and how many forms are there?
  5. the reason for this is because the html markup is broken. the value = '...' attribute needs quotes (either single or double quotes are valid) around the value. since this is inside of a double-quoted php string, use single-quotes in the markup.
  6. the reason you are having a hard time writing code, or are writing a ton of code that only differs in a name or value, to deal with your data is because your database design is bad. any time you find yourself with database table columns, variable names, or associative array names that have numerical endings, it's a sign that you are doing something wrong while programming. the point of databases is, each item (one, singular) of data is stored in its own row. you can then write simple queries and have simple code to retrieve any portion of the data you want. you also only store data that exists and wouldn't have 'slots' for each possible value. your data apparently corresponds to dates. you would instead have columns for the date (a mysql DATE YYYY-MM-DD data type) of the data, the value of the data, and perhaps an auto-increment id to uniquely identify and reference each data item. you would write a query that retrieves the data you want, in the order that you want it. you would then just display the data the way you want when you loop over the row(s) that the query returned.
  7. since you have a try/catch block around your code, that implies you have set the pdo error mode to exceptions. if this is true, why do you even have a conditional statement testing $stmt->execute() ? if the execute() method call fails, your code isn't going to be running any of that logic. it will be running the code in the catch{ } block.
  8. in php, empty is not the same thing that isset() tests. i suspect you mean a non-empty string? see the following example code - $flag_path = "http://aussietaste.recipes/wp-content/uploads/flags/"; // note: currency SYM and SYM$ map to just SYM due to trimming of any trailing $ by the code // define an array that maps input values to output values $map['USD'] = array('flag'=>'Flag_of_the_United_States.jpg','symbol'=>'$USD'); $map['GBP'] = array('flag'=>'Flag_of_the_United_Kingdom.jpg"','symbol'=>'£'); $map['£'] = array('flag'=>'Flag_of_the_United_Kingdom.jpg"','symbol'=>'£'); $map['AUD'] = array('flag'=>'Flag_of_Australia.jpg','symbol'=>'$AUD'); // add other mappings here... $currency = $product->currency != '' ? rtrim($product->currency,'$') : 'AUD'; // use value (less any trailing $) or default to 'AUD' if(!isset($map[$currency])) { // no mapping exists echo "The currency value {$product->currency} isn't defined."; } else { // the currency is defined, use it $arr = $map[$currency]; $cur = "<img src='$flag_path{$arr['flag']}' alt='' /> {$arr['symbol']} "; ?> <div class='prc'> <small> <?php if($product->saleprice > 0 && $product->saleprice < $product->price){ echo 'On Sale: <span style="font-weight: bold; color:red;">'; echo $cur; echo " [product.saleprice]</span>"; } else { echo $cur; echo " [product.price]"; } ?> </small> </div> <?php } ?>
  9. two things when programming - 1) Don't Repeat Yourself (DRY). you have two blocks of code that only differs in the On Sale: <span ...></span> text/markup. you should only write out program logic when you have different things you need to do. the common block of code, containing all the mapping of currency to flag image and display symbol, should not be repeated. 2) when all you are doing is mapping one value to other values, doesn't write out program logic (if/else/switch/case.) use a simple lookup array to do the mapping. by simplifying the code, it will be easy to see where and how you should ad the logic to default to the AUD value. i'll post some code showing how simply this can be done ....
  10. the only thing your form should submit is the radio button data. it should tell you which database table row the data corresponds to, as the name='Value[...]' key, and which radio button was selected, as the submitted value='1-5'. the only thing the UPDATE query should be SET'ing is the Value field, based on which row is being updated and which radio button was selected. the rest of your hidden form fields don't make any sense, mostly because they don't relate the submitted data to the row it corresponds to. if you define the table holding the user's choices as i suggested, the user_id/QuestionID pair identifies which row to UPDATE and your existing radio button form field is correct. if you instead have an auto increment column defined for that table, which i'm guessing is what the AnswerID is, you would use it as the name= 'Value[...]' key, instead of the QuestionID. in either case, the keys of the $_POST['Value'] field will tell you which row the submitted radio button data corresponds to. your loop would look like - foreach($_POST['Value'] as $key=>$value) { // $key will tell you which row to update, $value will be the selected radio button value 1-5 } the UserID value you use in the database query should be coming from your user-system php code. it shouldn't be coming from the form since that would allow a user to alter someone else's data.
  11. i would start by storing/defining the QuestionID and Questions (text) in one table and the user's choices in a different table. you would store the user_id, QuestionID, and the choice value (1-5) in the second table. the user_id/QuestionID (together) would be defined as a unique composite index to enforce uniqueness. this will also let you use an INSERT ... ON DUPLICATE KEY UPDATE query to either insert new data or update existing data.
  12. the following implements your logic, saving the output from each input .htm file to a corresponding .csv file - <?php ini_set('display_errors',1); error_reporting(E_ALL); $stats_wanted = array('playedPositionsShort', 'name', 'playerId', 'age', 'rating', 'shotOnTarget', 'shotsTotal', 'penaltyScored', 'penaltyMissed', 'passLongBallAccurate', 'passLongBallTotal', 'passTotal', 'passCrossAccurate', 'passCrossTotal', 'passThroughBallTotal', 'passThroughBallAccurate', 'keyPassTotal', 'dribbleWon', 'dribbleTotal', 'tackleWon', 'tackleLost', 'tackleWonTotal', 'tackleTotalAttempted', 'challengeLost', 'interceptionLost', 'penaltyTaken', 'interceptionAll', 'clearanceTotal', 'offsideGiven', 'offsideProvoked', 'foulGiven', 'foulCommitted', 'dispossessed', 'duelAerialWon', 'duelAerialLost', 'duelAerialTotal', 'touches', 'totalPasses', 'offsideWonPerGame', 'offsideGivenPerGame', 'passSuccessInMatch' ); $keys = array_flip($stats_wanted); // change stats wanted into keys $source_path = 'directory/'; $dest_path = ''; // enter the path, with trailing /, where you want the destination files to be written foreach (glob("$source_path*.*") as $filename) { echo "Processing: $filename<br>"; $info = pathinfo($filename); // get the ['filename'] $content = json_decode(file_get_contents($filename),true); // read file contents as an array $output = fopen("$dest_path{$info['filename']}.csv",'w'); // create output file fputcsv($output, $stats_wanted); // write header line to file // loop over players in the data foreach($content['playerTableStats'] as $arr){ $arr = array_intersect_key($arr,$keys); // keep only the stats wanted elements fputcsv($output, $arr); // write the data to the file } fclose($output); // close the current file } this makes the same assumption that your code does, that the order of the $stats_wanted elements matches the order that the data elements will exist as. if not, you can throw in a sort operation before writing the data to the file.
  13. what tool/software are you using to assign privileges to the database? you may need to explicitly flush the privileges to get them to take effect. another possibility is if you have a typo or some white-space as part of the value(s) in the php code.
  14. are you sure of the database server hostname for the new domain? it may in fact be different from any previous domain. are you sure of the database username and database name? a lot of web hosting requires the hosting account name as part of the database username. after you created the database username/password, did you assign that database username privileges to the database you are trying to use?
  15. the code developed in the thread, but for an update query - $cols = array(); $types = ''; // string holding the i,s,d,b types $params = array(); // holds references to data values in the same order as the field names and types foreach($fieldarray as &$field){ $cols[] = "SET {$field[2]} = ?"; $types .= $field[26]; $params[] = &$field[25]; } // add the types/params for the id $types .= 'i'; $params[] = $id; $query = "UPDATE $ap ".implode(',',$cols)." WHERE ID = ?"; $stmt = $db->prepare($query); $refArr = array_merge(array($types),$params); // array of the bind_param parameters $ref = new ReflectionClass('mysqli_stmt'); // use class reflection to call mysqli->bind_param dynamically $method = $ref->getMethod("bind_param"); $method->invokeArgs($stmt,$refArr); // 'call' the actual bind_param method $stmt->execute();
  16. your code to build and run an UPDATE query would use the same method as for the insert query. you need to build the complete sql query statement in $query, a string of the input types in $types, and an array of input parameters in $params. after you have finished looping to build the set col = ? terms in an array, implode them and put them into the sql query statement. then add the final parts to $query, $types, $params for the WHERE id = ? part of the query. you would reuse the common code from the ->prepare() statement through the ->execute() statement. in fact, in general, the code from the ->prepare() statement through the ->execute() statement would be part of a class method that would accept the $query, $types, and $params as inputs that you just call any time you need to run a prepared query.
  17. if you had php's error reporting set to E_ALL and display_errors set to ON, you would be getting a warning that would alert you to what's going on. amazingly, i have used (past tense, i don't think anyone uses mysqli with prepared queries) this code, error free, with a value coming from the array being looped over. perhaps a php version change. to get the current code to work, you need one more & in the foreach() - foreach($fieldarray as &$field){ are you sure you don't want to switch to PDO? this is a lot of extra code just to call one php built in method.
  18. every single character in the example code i posted was there for some reason. in particular there's one & that's required to make it work. also see the comment on the $params array - // holds references to data values in the same order as the field names and types
  19. the following is what you would have to do if using mysqli (thanks php, just because you can make a function with a variable number of arguments for same meaning values, doesn't mean you should) - $fieldarray[] = array('name'=>'firstname','type'=>'s','value'=>'john'); $fieldarray[] = array('name'=>'lastname','type'=>'s','value'=>'doe'); $fieldarray[] = array('name'=>'email','type'=>'s','value'=>'[email protected]'); $cols = array(); $types = ''; // string holding the i,s,d,b types $params = array(); // holds references to data values in the same order as the field names and types foreach($fieldarray as $field){ $cols[] = $field['name']; $types .= $field['type']; $params[] = &$field['value']; } $holders = array_fill(0,count($cols),'?'); $query = "INSERT INTO $table_name (".implode(',',$cols).") VALUES (".implode(',',$holders).")"; $stmt = $conn->prepare($query); $refArr = array_merge(array($types),$params); // array of the bind_param parameters $ref = new ReflectionClass('mysqli_stmt'); // use class reflection to call mysqli->bind_param dynamically $method = $ref->getMethod("bind_param"); $method->invokeArgs($stmt,$refArr); // 'call' the actual bind_param method $stmt->execute();
  20. my post states what you would need to do to do this using the mysqli database library. the code i posted uses the PDO database library, which was mentioned both in the text and in a comment in the code. you cannot mix calls to different database libraries.
  21. to dynamically build and run the mysqli bind_param() statement requires that you use either call_user_func_array() or use reflection to call the method. there are examples of doing this in the php.net user contributed notes for the bind_param() statement. however, this is a problem with using mysqli. it is much easier if you use PDO, since each bindParam()/bindValue() statement is called separately. you can just loop over the array of input values and call bindParam()/bindValue() inside the loop. note: if you are only using a query once, use bindValue() as it avoids the overhead of evaluating the bound variables when the ->execute() method is called. for your insert query specific code, see the following - $fieldarray[] = array('name'=>'firstname','type'=>PDO::PARAM_STR,'value'=>'john'); $fieldarray[] = array('name'=>'lastname','type'=>PDO::PARAM_STR,'value'=>'doe'); $fieldarray[] = array('name'=>'email','type'=>PDO::PARAM_STR,'value'=>'[email protected]'); $cols = array(); foreach($fieldarray as $field){ $cols[] = $field['name']; } $holders = array_fill(0,count($cols),'?'); $query = "INSERT INTO $table_name (".implode(',',$cols).") VALUES (".implode(',',$holders).")"; $stmt = $conn->prepare($query); // using PDO, the bind loop would look like - $parm = 1; foreach($fieldarra as $field){ $stmt->bindValue($parm++, $field['value'],$field['type']); } $stmt->execute(); if you are at the database-layer in your code, your application would have already validated any external data so that it makes sense to the application, required fields are not empty, any specific constraints/formats have been checked. at the database-layer, you are protecting against things like sql special characters from breaking the sql syntax or in the case where the format permits content that could contain sql statements (a blog/forum post for example), to protect against sql injection.
  22. here's an edit to the above (the forum software cut my edit time limit off mid edit) - edit: here's trick that should work. you can use sqlsrv_num_fields($stmt) to find if the result set contains any field/column definition, from a SELECT/SHOW query, regardless of there being any rows in the result set. you could loop while sqlsrv_next_result($stmt) is true and if sqlsrv_num_fields($stmt) is true, there's a SELECT/SHOW result set that you can fetch row(s) from.
  23. these result sets correspond to each of the insert queries for the temp tables. if you echo sqlsrv_rows_affected($stmt); before each of the sqlsrv_next_result($stmt); lines, you should get an integer value that's the number of rows that were inserted by each query. i don't know if there's a way of suppressing/resetting this. perhaps in the ms sql stored procedure documentation.
  24. this indicates that there is more than one result set. put 3-4 of the var_dump(sqlsrv_next_result($stmt)); lines in a row to see how many result sets there are. true values indicate a result set. a null value indicates no more result sets. at this point, i would guess that your stored procedure is running several queries (insert/update/delete/select), each stacking a result into the returned data. if this is the expected operation of the procedure and not due to a logic problem, you will need to call enough sqlsrv_next_result($stmt); statements to get to the actual one holding the data. based on the default cursor type usage, it looks like the false value for the num_rows() statement is the expected.
  25. you need to start digging into what you are getting back. any chance you have multiple databases and the one you selecting on the connection doesn't have any matching data? what does adding the following show - var_dump(sqlsrv_num_rows($stmt)); do you have php's error_reporting/display_errors set to report and display all php detected errors? echo some literal string inside the while(){} loop so that you will know if it is running - echo 'in loop'; also, use var_dump($row); inside the loop to see what exactly is in $row, assuming the while loop is running. if there's no apparent output from your page, what does a 'view source' in your browser show? and is that all of your actual code in the file? with nothing later in the file that could be hiding/discarding the output, such as a header() redirect and nothing removed between where the query is ran and where you are looping over the result? edit: also, try the above things both with and without the sqlsrv_next_result($stmt); line, but change that line to be var_dump(sqlsrv_next_result($stmt)); so that you can tell if there actually is a next result set (this particular stored procedure may be returning multiple result sets for some reason.)
×
×
  • 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.