-4

I'm working on a project and I have to retrieve a MySQL data by a php code. I've already put all the informations in the database, put it isn't showing when I compile the php. Can someone help and tell me what is possibly wrong?

<?php
$dbName = "dbname";
$serverName = "xxx.xxx.xxx";
$mySqlUser = "user";
$mySqlSenha = "password";
$mConn = mysqli_connect($serverName, $mySqlUser, $mySqlSenha, $dbName);


if ($mConn) {
    echo "Conexão aberta com sucesso";
}
else {
    echo "A conexão não foi aberta";
}

$sql = "SELECT ponto_trajeto_latitude, ponto_trajeto_longitude FROM tb_pontos_trajeto";

$result = mysqli_query($mConn, $sql);

$responde = array();

echo "<table border = '3'>";
echo "<tr>";
     echo "<th> Latitude </th>";
     echo "<th> Longitude </th>";        
echo "</tr>";


if($result = mysqli_query($mConn, $sql)) {
    if(mysqli_num_rows($result) > 0) {

    while($row = mysqli_fetch_array($result)) {
    $response = array("latitude" => $row[0], "longitude" => $row[1]);

    echo "<tr>";
         echo "<td>". $row['latitude'] ."</td>";
         echo "<td>". $row['longitude'] ."</td>";
    echo "</tr>";

}   
} else {
        echo "<br><br>Não há registros.";
    }

} else {
    echo "ERRO: Não foi possível executar o $sql" . mysqli_error($mConn);

}


echo "</table>";

echo JSON_encode(array("data" =>$responde));


?>

OKAY, so as you asked, here it is what I'm seeing. And sorry for any little problems, I'm new on it and new on this site. And, I just want to show the latitude and longitude, so I thought that the others informations isn't necessary. What i'm doing is a project that it envolves Android studio as well, but I've been told to do the php thing and test it if it's working before to do something in android.

The data

And the php, "não há registro" means that doesn't have registers, but as you can see by the picture above, it has

  • 1
    Put `error_reporting(E_ALL); ini_set('display_errors', 1);` before `$mConn = ...` and see what error message you are receiving. –  Nov 18 '17 at 23:32
  • @aendeerei I put it, but unfortunateIy didn't receive anything. – Sabrina T. Nov 18 '17 at 23:41
  • 1
    That's impossible :-) Could you please also update your question with them in it? –  Nov 18 '17 at 23:43
  • Saw it and updated the post, I'm kind of a newbie in this site, so i'm sorry – Sabrina T. Nov 19 '17 at 00:05
  • If you print something (like your `table` lines) before `json_encode(...)` you'll also receive an error when the json-encoded response is sent to your ajax call. –  Nov 19 '17 at 00:13

2 Answers2

0
$row = mysqli_fetch_array($result, MYSQLI_NUM)

try this in your while loop

Orhan Esin
  • 46
  • 7
0

The problems in your code:

Problem 1:

It should be:

echo "<td>" . $response['latitude'] . "</td>";
echo "<td>" . $response['longitude'] . "</td>";

or:

echo "<td>" . $row['ponto_trajeto_latitude'] . "</td>";
echo "<td>" . $row['ponto_trajeto_longitude'] . "</td>";

or:

echo "<td>" . $row[0] . "</td>";
echo "<td>" . $row[1] . "</td>";

Problem 2:

It should be $response instead of $responde overall. Or $responde instead of $response. But not both.


A code proposal:

Don't worry, the comments are long, but the actual code is short.

Feel free to ask anything.

Good luck.

<?php

// Db configs.
define('HOST', 'localhost');
define('PORT', 3306);
define('DATABASE', 'dbname');
define('USERNAME', 'user');
define('PASSWORD', 'pass');

// Error reporting.
error_reporting(E_ALL);
ini_set('display_errors', 1); // SET IT TO 0 ON A LIVE SERVER!

/**
 * Enable internal report functions. This enables the exception handling, 
 * e.g. mysqli will not throw PHP warnings anymore, but mysqli exceptions 
 * (mysqli_sql_exception). They are catched in the try-catch block.
 * 
 * MYSQLI_REPORT_ERROR: Report errors from mysqli function calls.
 * MYSQLI_REPORT_STRICT: Throw a mysqli_sql_exception for errors instead of warnings. 
 * 
 * See: http://php.net/manual/en/class.mysqli-driver.php
 * See: http://php.net/manual/en/mysqli-driver.report-mode.php
 * See: http://php.net/manual/en/mysqli.constants.php
 */
$mysqliDriver = new mysqli_driver();
$mysqliDriver->report_mode = (MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

/**
 * Create a new db connection.
 * 
 * @see http://php.net/manual/en/mysqli.construct.php
 */
$connection = new mysqli(HOST, USERNAME, PASSWORD, DATABASE, PORT);

$sql = 'SELECT 
            ponto_trajeto_latitude,
            ponto_trajeto_longitude 
        FROM tb_pontos_trajeto';

/*
 * Prepare the SQL statement for execution - ONLY ONCE.
 * 
 * See: http://php.net/manual/en/mysqli.prepare.php
 */
$statement = $connection->prepare($sql);

/*
 * Execute the prepared SQL statement.
 * When executed any parameter markers which exist will 
 * automatically be replaced with the appropriate data.
 * 
 * See: http://php.net/manual/en/mysqli-stmt.execute.php
 */
$executed = $statement->execute();

/*
 * Get the result set from the prepared statement.
 * 
 * NOTA BENE:
 * Available only with mysqlnd ("MySQL Native Driver")! If this 
 * is not installed, then uncomment "extension=php_mysqli_mysqlnd.dll" in 
 * PHP config file (php.ini) and restart web server (I assume Apache) and 
 * mysql service. Or use the following functions instead:
 * mysqli_stmt::store_result + mysqli_stmt::bind_result + mysqli_stmt::fetch.
 * 
 * See:
 *      http://php.net/manual/en/mysqli-stmt.get-result.php
 *      https://stackoverflow.com/questions/8321096/call-to-undefined-method-mysqli-stmtget-result
 */
$result = $statement->get_result();

/*
 * Fetch data - all at once - and save it into $fetchedData array (associative array).
 * It looks like this. Each array item represents a record in db table.
 * 
 * Array
 * (
 *     [0] => Array
 *         (
 *             [ponto_trajeto_latitude] => 50.43
 *             [ponto_trajeto_longitude] => 8.368
 *         )
 * 
 *     [1] => Array
 *         (
 *             [ponto_trajeto_latitude] => 48.34
 *             [ponto_trajeto_longitude] => 8.23476
 *         )
 * 
 * )
 * 
 * See: http://php.net/manual/en/mysqli-result.fetch-array.php
 */
$fetchedData = $result->fetch_all(MYSQLI_ASSOC);

// ... OR fetch one row at a time, instead of using fetch_all().
// while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
//     $fetchedData[] = $row;
// }

/*
 * Free the memory associated with the result. You should 
 * always free your result when it is not needed anymore.
 * 
 * See: http://php.net/manual/en/mysqli-result.free.php
 */
$result->close();

/*
 * Close the prepared statement. It also deallocates the statement handle.
 * If the statement has pending or unread results, it cancels them 
 * so that the next query can be executed.
 * 
 * See: http://php.net/manual/en/mysqli-stmt.close.php
 */
$statementClosed = $statement->close();

// Just for testing (delete it): Display fetched data.
echo '<pre>' . print_r($fetchedData, TRUE) . '</pre>';

echo json_encode($fetchedData);

Code differences:

The main difference:

As you probably know, each input value coming from the user (e.g. browser) is a potential threat to your system. The process of passing such harmful values into the data access layer is named "SQL injection". So they should/must be validated, filtered, sanitized, escaped, (encoded if needed).

mysqli_query can not "secure" the input values passed to the sql statement. So, each value must be treated separately from this point(s) of view, before being passed into the sql statement. Especially the escaping mechanism is important in avoiding eventual harmful effects.

In comparison, by preparing an sql statement using prepare() (followed by bind_param() and execute()), all potentially harmful input values are automatically escaped by the PHP engine, and are therefore transformed in harmless values.

That's the big picture. For more details regarding the SQL injection see the (accepted) answers from here and here, and read How to use mysqli properly, for example.

In your code you didn't pass any input values into the sql statement. E.g: you have, for example, no WHERE clause. So, you could have further used mysqli_query() without any security issues. But, if you would have needed something like ... WHERE id = $pontoTrajetoId ..., then mysqli_query would not have been able to protect your system from an eventually harmful value of the variable $pontoTrajetoId. Instead, prepare() would have done a great job on this part.

The second difference:

The 2nd difference relies in the use of fetch_all() in my code, compared with the need of a while($row = mysqli_fetch_array($result)) {...} loop in your code. If you read my code, under fetch_all() you'll discover the same while loop as an alternative (commented). The difference is just, that fetch_all() fetches all records in an array, at once. On the other hand, fetch_array() reads only one record (at a time).

The third difference:

The difference resides in the "activation" of error reporting - in my code, with two-three lines of code.

By default, the PHP engine triggers an error every time a failure occurs in any PHP function. Please note that there are multiple error types/levels in PHP: notices, warnings, fatal errors, etc. By using

error_reporting(E_ALL);
ini_set('display_errors', 1); // SET IT TO 0 ON A LIVE SERVER!

I am just telling PHP that I need it to display all errors, e.g. of any level, on screen.

Because all mysqli functions are part of PHP, they throw anyway errors (of type warning) on failure. But, by using

$mysqliDriver = new mysqli_driver();
$mysqliDriver->report_mode = (MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

I am telling PHP to treat and throw them as exceptions. Read this.

Now, here you'll have to be very careful, to NOT display any data from the original error on the screen when you are deploying your website on the live server. That's why I commented like this:

ini_set('display_errors', 1); // SET IT TO 0 ON A LIVE SERVER!

Why? Because many errors are described by a lot of sensitive details (error message, error number, the file and line in which the error was raised, etc), which can provide too much informations regarding your sytem to an unknown user. The proper way to go with this would be to activate the logging of the errors in log files and either display a general, user-friendly error message to the user, or show a user-friendly html page containing a general error message in it - like "Unfortunately an error occurred during your request. Please try again or contact our support team".

The logging and the error/exception page/message display should be handled inside two functions of your choice. Condition is, that the names of the two functions are to be passed as arguments to the following functions: set_error_handler() and set_exception_handler(). If needed, you can involve a third function too. Its name should be then passed to register_shutdown_function(), which "* Registers a callback to be executed after script execution finishes or exit() is called.*".

In order to perfectly understand how you should correctly proceed with the error reporting, read this and this. It's easy to understand and follow.

Bottom line, instead of validating the result of a mysqli_query(), or checking the presence of a connection error by calling mysqli_error() - as you did in your code, I just let the PHP engine do his job: to throw an error/exception by itself and to display it on screen. Again, read the error reporting links that I gave you.

Well, I hope I could guide your next steps and, if you have more questions, just ask. I'll be happy to answer.

  • thank you so much for the code and its comments explaining everything I'll check it all for sure, and so sorry for you to make a code. By the way, our codes are completely different, could you explain why? – Sabrina T. Nov 19 '17 at 00:54
  • @SabrinaT. I just finished my explanations. I reedited my answer. Have fun. –  Nov 19 '17 at 02:06
  • thank you so much for your explanation! I'll surelly pass these useful informations for my project group, we're starting doing complex things now because we've learned just the basic and we wanted to do something cooler than the projects that were passed for us, so we didn't know that much as you, then we/I really apreciate that u've shared these informations!! :) bye. – Sabrina T. Nov 19 '17 at 05:49
  • @SabrinaT. You are welcome. Please keep in mind that the prepared statements, the error reporting system and the exception handling are main elements of a properly set and secured data access layer. Therefore I suggest you to understand them thoroughly before going further with your projects. Well, good luck! :-) –  Nov 19 '17 at 10:51
  • @SabrinaT. One last important thing: I would suggest you to use the **PDO** library, instead of mysqli. There are good reasons to do this. It is for sure simpler, eleganter and flexibler. The using principles of PDO are the same as of mysqli, so it shouldn't be a problem to move to it within an hour or two, at most. Here are two excelent resources: [this](https://phpdelusions.net/pdo) and [this](http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers). And, of course, the corresponding [php.net docs](http://php.net/manual/en/book.pdo.php), including their great examples and comments. –  Nov 19 '17 at 11:14