No funciona código en servidor pero sí en localhost (no muestra gráfico)

publicado por: Anonymous

Tengo una pagina la cual me gráfica unos datos de MySql, funciona perfectamente en mi localhost pero no en el servidor Cpanel es decir no me muestra la gráfica con los datos de la DB.

Las especificaciones de del servidor web localhost son:

  • Apache/2.4.25 (Win32) OpenSSL/1.0.2j PHP/5.6.30
  • Versión del cliente de base de datos: libmysql – mysqlnd 5.0.11
  • extensión PHP: mysqliDocumentación curlDocumentación mbstringDocumentación
  • Versión de PHP: 5.6.30

Las especificaciones de del servidor web externo(Cpanel) son:

  • cpsrvd 11.66.0.25
  • Versión del cliente de base de datos: libmysql – 5.1.73
  • extensión PHP: mysqliDocumentación curlDocumentación
    mbstringDocumentación
  • Versión de PHP: 5.6.30

El código que tengo es el siguiente, es el mismo en ambos casos a excepción obvio de la conexión a la DB:

HTML

<script src="../hw/Highcharts/js/highcharts.js"></script>
<script src="../hw/Highcharts/js/jquery.js"></script>

<div class="caja">
    <select name="ANO" id="ANO" autofocus="autofocus">
        <option>Seleccione...</option>
        <option value="2014">2014</option>
        <option value="2015">2015</option>
        <option value="2016">2016</option>
        <option value="2017">2017</option>
        <option value="2018">2018</option>
    </select>
</div>

<div class="caja">
    <select name="MES" id="MES">
        <option>Seleccione...</option>
        <option value="01">ENERO</option>
        <option value="02">FEBRERO</option>
        <option value="03">MARZO</option>
        <option value="04">ABRIL</option>
        <option value="05">MAYO</option>
        <option value="06">JUNIO</option>
        <option value="07">JULIO</option>
        <option value="08">AGOSTO</option>
        <option value="09">SEPTIEMBRE</option>
        <option value="10">OCTUBRE</option>
        <option value="11">NOVIEMBRE</option>
        <option value="12">DICIEMBRE</option>
    </select>
</div>

PHP

<?php require_once('../../Connections/conexion.php'); ?>

<?php

$MES = $_POST['MES']; 
$ANO = $_POST['ANO']; 
$resultado = [];

for ($i = 0; $i <= 31; $i++) { 
$query= "SELECT SUM(monto_venta) AS r FROM pruebas WHERE 
DAY(fecha_venta)='$i' AND MONTH(fecha_venta)='$MES' AND YEAR(fecha_venta) = 
'$ANO'"; 

$result =  mysql_query($query, $conexion); 
$valor = mysql_result($result, 0); 
$resultado[] = round($valor, 1); 
} 

echo json_encode($resultado);

?>

solución

Tu código carece de comprobaciones de condiciones de error por lo que si falla en alguna parte tendrás resultados imprevistos (como los que sufres).

Solución propuesta

Una forma correcta de hacer el trabajo es la siguiente:

<?php
/* No requieres los paréntesis para una construcción del lenguaje */
require_once '../../Connections/conexion.php';

/* Es importante escapar las cadenas antes de agregarlas a una consulta SQL */
$MES = mysql_real_escape_string($_POST['MES']);
$ANO = mysql_real_escape_string($_POST['ANO']);
$resultado = [];

/* NOTA: ¿Realmente necesitas buscar el dato del día 0? */
for ($i = 0; $i <= 31; $i++) { 
  $query = "
    SELECT SUM(monto_venta) AS r
    FROM pruebas
    WHERE
      DAY(fecha_venta) = '$i'
    AND
      MONTH(fecha_venta) = '$MES'
    AND
      YEAR(fecha_venta) = '$ANO'
  ";
  $result = mysql_query($query, $conexion);
  /* Comprobamos si la consulta produjo un error */
  if ($result === false) {
    die('Error SQL: ' . mysql_error());
  }
  $valor = mysql_result($result, 0);
  $resultado[] = round($valor, 1);
}
/* Es importante indicar el tipo de información que devolvemos */
header('Content-Type: application/json');
echo json_encode($resultado);

Es posible que este código no solucione tu problema (probablemente sufras algún problema relacionado con el esquema de la base de datos o con el montaje de la consulta SQL), pero te ayudará a determinar el error gracias a su control de error y escapado de cadenas que explicaré a continuación.

Escapado de cadenas

Debes hacer uso de mysql_real_escape_string() cada vez que quieras insertar cadenas que están fuera de tu control a una consulta SQL o bien usar consultas preparadas a través de PDO o mysqli. La inyección SQL es un problema serio que debes tener siempre en cuenta.

Control de errores

Si no compruebas si la consulta SQL se realizó de manera satisfactoria estarás ejecutando código con un contenido incorrecto en la variable que almacena el resultado de la consulta.

Cabeceras HTTP para datos JSON

Para terminar deseo apuntar que es recomendable enviar en las cabeceras HTTP información sobre el tipo de datos devueltos por el script. En este caso he indicado que es un JSON con el valor application/json en la cabecera Content-Type.


Optimización

Habiendo revisado por segunda vez el código quería ofrecerte la posibilidad de optimizar tu código reduciendo el número de consultas SQL que realizas a la base de datos.

<?php
/* No requieres los paréntesis para una construcción del lenguaje */
require_once '../../Connections/conexion.php';

/* Es importante escapar las cadenas antes de agregarlas a una consulta SQL */
$MES = mysql_real_escape_string($_POST['MES']);
$ANO = mysql_real_escape_string($_POST['ANO']);

/* NOTA: ¿Realmente necesitas enviar el dato del día 0?
  generamos una matriz del 0 al 31 (32 elementos) con valor 0 */
$resultado = array_fill(0, 32, 0);
/* La consulta ahora es algo más sencilla */
$query = "
  SELECT
    SUM(monto_venta) r,
    DAY(fecha_venta) dia
  FROM pruebas
  WHERE
    MONTH(fecha_venta) = '$MES'
  AND
    YEAR(fecha_venta) = '$ANO'
";
$result = mysql_query($query, $conexion);
/* Comprobamos si la consulta produjo un error */
if ($result === false) {
  die('Error SQL: ' . mysql_error());
}
/* Obtenemos los datos uno a uno */
while (($valor = mysql_fetch_assoc($result)) !== false) {
  /* Sólo modificamos el valor de los días obtenidos en cada registro existente */
  $resultado[$valor['dia']] = round($valor['r'], 1);
}
/* Es importante indicar el tipo de información que devolvemos */
header('Content-Type: application/json');
echo json_encode($resultado);

De esta manera en una única consulta SQL obtienes sólo los datos contenidos en la base de datos, evitando buscar aquellos que no existan.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *