0

Vale como podemos observar en mi CRUD tengo dos columnas y en algunas de ellas a veces se puede visualizar le caracter "&".

Yo quiero editar cualquier columna y puedo hacerlo perfectamente. http://imgur.com/a/cWPBr Selecciono el boton de editar y automaticamente arriba en las cajas aparece y puede ser editable.

Pero si selecciono alguno que tenga "&" no visualiza nada pero si recoge el dato por la URL. http://imgur.com/a/ievHj

La conexion de PDO que tengo es la siguiente

public function __CONSTRUCT()
{
    try
    {
        $this->pdo = new PDO('mysql:host=localhost;dbname=deimos1;charset=UTF8', 'root', '');
                    $this->pdo->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
                    $this->pdo->exec("SET NAMES 'utf8';");
    }
    catch(Exception $e)
    {
        die($e->getMessage());
    }
}

No modifico ni contraseña ni pass ya que son las de por defecto ya que esto son pruebas.

Y esta seria la parte en la que debe de obtener los datos que fue la que modifique antes con lo que me comentastes.

public function Obtener($acronimo) {
    try {
        $stm = $this->pdo->prepare('SELECT * FROM categoria WHERE acronimo = ?');
        $stm->execute(array($acronimo));
        $r = $stm->fetch(PDO::FETCH_ASSOC);

        $alm = new Categoria();

        $alm->__SET('acronimo', $r["acronimo"]);
        $alm->__SET('categoria', $r["categoria"]);

        return $alm;
    } catch (Exception $e) {
        die($e->getMessage());
    }
}

Los datos yo los obtengo por aqui:

<?php foreach ($model->Listar() as $r): ?>
                    <tr>
                        <td><?php echo $r->__GET('acronimo'); ?></td>
                        <td><?php echo $r->__GET('categoria'); ?></td>

                        <td>
                            <a href="?action=editar&id=<?php echo $r->acronimo; ?>"><img src="icon_editthis.png" width="30px" height="30px"/></a>
                        </td>
                        <td>
                            <a href="?action=eliminar&acronimo=<?php echo $r->acronimo; ?>"><img src="delete.png" width="30px" height="30px"/></a>
                        </td>
                    </tr>
  • Claro es que PHP usa & para separar las variables que pasas en el POST, o sea que para pasar varios datos PHP hace algo como action=editar&id=1&nombre=Juan&apellido=Díaz ... al empezar tu id por el símbolo & PHP interpreta que id es igual a vacío o nulo: &id=&CC Lo mejor sería pasar al POST otro campo si es numérico mejor en vez de aventurarse en soluciones complicadas. Por eso casi siempre los campos id son numéricos. En cuanto al PDO tienes seteado dos veces el charset, con una basta. – A. Cedano Apr 21 '17 at 11:34
  • Modifique de nuevo el POST e introduci un ultimo apartado de como recibo los datos, pero pasarlo ahora por POST me quedao en blanco, por que en el codigo fuente parece que is lo recibe bien: Eset es el valor que devuelve--->>>//// El esta obteniendo el dato el problema creo que es el punto y coma que establece detras no? – Alberto Cepero de Andrés Apr 21 '17 at 11:50
  • He actualizado mi respuesta explicando lo que pasa. Si tienes en tu tabla categoria otra columna, por ejemplo autoincremental, esa es la que debes usar para filtrar los datos. Pues usar campos con caracteres especiales para pasarlos en una URL es problemático. – A. Cedano Apr 21 '17 at 11:59

2 Answers2

1

Usa fetchObject() en vez de fetch() si quieres tratar las filas como objetos y poder usar sus propiedades.

$r = $stm->fetchObject(PDO::FETCH_OBJ);
cnbandicoot
  • 2,614
  • 8
  • 24
  • ¿No sería lo mismo al estar utilizando `fetch(PDO::FETCH_OBJ)`? – Mariano Apr 21 '17 at 07:49
  • Me da este error, y no entiendo porque no se que es dicha clase. Fatal error: Class '5' not found in C:\xampp\htdocs\ScriptBBDD\2\alumno.model.php on line 52 – Alberto Cepero de Andrés Apr 21 '17 at 07:49
  • @Alberto, no crees que sería conveniente que indicaras cuál es la línea 52? – Mariano Apr 21 '17 at 08:03
  • $r = $stm->fetch(PDO::FETCH_OBJ); //Esa es la línea lo sienot por tardar estaba liado con le jefe Por cierto me estoy dando cuenta que donde puede que este recibiendo el problema es por los "&" porque en algunos sitios necesito poner por ejemplo "D&C" y puedo ingresarlo perfectamente a la BBDD pero recogerlo me da error. – Alberto Cepero de Andrés Apr 21 '17 at 08:47
  • Estoy tratando que cobtenga los "&" que se encuentran en algunos datos de las BBDD de la siguiente manera, pero sigue dando error. public function Obtener($acronimo) { try { $stm = $this->pdo->prepare('SELECT * FROM categoria WHERE acronimo = ?'); $stm->execute(array($acronimo)); $r = $stm->fetch(PDO::FETCH_OBJ); $alm = new Categoria(); $alm->__SET('acronimo', htmlspecialchars($r->acronimo)); $alm->__SET('categoria', htmlspecialchars($r->categoria)); return $alm; } catch (Exception $e) { die($e->getMessage()); } } – Alberto Cepero de Andrés Apr 21 '17 at 09:48
0

ACTUALIZACIÓN

Cuando enviamos valores por PHP en una URL, el lenguaje usa por defecto el símbolo & para separar los diferentes valores. Si te fijas en la barra de navegación verás:

... index.php?action=editar&id=&CC

Significa que todo lo que hay después del símbolo ? son valores que se pasan al servidor y que luego se obtienen por _$POST, por _$GET, etc.

Supongamos algo como esto:

... index.php?action=editar&id=1&nombre=Juan&apellido=Mendez

entre cada & habrá valores de forma asociativa: id=1 nombre=Juan apellido=Mendez

que luego se obtienen por $_POST["id"], $_POST["nombre"], etc.

El problema es que en tu caso: action=editar&id=&CC id es igual a nulo o vacío, porque la &que hay antes de CC lo que hace es indicar a PHP que empieza otra variable llamada CC.

Solución:

Usar en vez de ese valor, otro valor que identifique de manera única las filas de tu tabla, si es un valor numérico mejor, por ejemplo, la columna autoincremental de la tabla.

Si la tabla categoria tuviese un campo numérico llamado por ejemplo id_categoria que indentifique de forma unívoca cada fila de la tabla, es mejor pasar ese campo:

    $alm->__SET('categoria', $r["id_categoria"]);

Entonces tu URL se presentaría por ejemplo así:

... index.php?action=editar&id=8945

luego obtienes id con _$GET o con $_POST. Ejemplo:

$id=_$GET["id"];

y le pasas el valor de $id en el WHERE id_categoria=?.


En cuanto a la conexión PDO, tienes establecido dos veces el charset. Es decir, que esta línea sobra:

$this->pdo->exec("SET NAMES 'utf8';");

pues más arriba ya estableciste el charset haciendo:

$this->pdo->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");


@deprecated

En realidad el problema de las ñ y las dos noticias (que no es lo mismo que error) que estás teniendo, son dos cosas distintas.

A. El problema de las ñ

Es un problema de codificación de caracteres. El cual puede encontrarse en varios niveles.

Ya has dicho que el HTML está bien:

<meta http-equiv="Content-Type" content="text/html"; charset=utf-8"/>

entonces es muy probable que el problema sea que, al hacer tu conexión PDO no le estés indicando que se conecte con el charset utf-8. Puedes consultar al respecto lo que dice el Manual de PHP. A veces, aunque el charset de la base de datos esté bien, no se presenta correctamente si no indicamos en la conexión que queremos usar el charset utf-8.

Ejemplos de conexión seteando el charset:

$pdo = new PDO("mysql:host=localhost;dbname=DB;charset=UTF8");

o bien:

<?php
$dsn = 'mysql:host=localhost;dbname=testdb';
$username = 'username';
$password = 'password';
$options = array(
    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
); 

$dbh = new PDO($dsn, $username, $password, $options);
?>

Si ya tienes bien seteado el charset en la BD y en la conexión y te sigue dando problema de las ñ, entonces habría que verificar que esa columna que te está arrojando valores con problemas tiene la buena codificación en la base de datos o bien en último término hay que pensar en establecer el charset en la configuración del servidor (PHP u otro) a utf-8.

Sobre los problemas de codificación puedes ver también la respuesta a esta pregunta: � Caracter inspector aparece en algunos datos obtenidos de la BBDD

B. Las dos noticias

Notice: Trying to get property of non-object in C:\xampp\htdocs\ScriptBBDD\2\alumno.model.php on line 56

Notice: Trying to get property of non-object in C:\xampp\htdocs\ScriptBBDD\2\alumno.model.php on line 57

indican que estás intentando de acceder a una propiedad de un objeto que no existe. O sea, es como si objeto no existiese y tu hicieras esto: objeto->dame_esta_propiedad();. Entonces el código te dice: pero buenooo, objeto no existe, esa propiedad no puedo dártela. Es una noticia, o sea, PHP te informa de que eso no está bien, pero te lo deja pasar y por eso el código funciona. Si fuese un error verías seguramente tu pantalla en blanco.

¿Dónde estás haciendo eso? En dos líneas de tu código, las líneas 56 y 57 de tu código.

¿Serán estas dos?:

    $alm->__SET('acronimo', $r->acronimo);
    $alm->__SET('categoria', $r->categoria);

Es muy probable. Si acronimo y categoria son dos columnas de tu base de datos y quieres setear esos valores a la variable $alm no estás haciendo bien.

Puedes hacer esto:

$r = $stm->fetch(PDO::FETCH_ASSOC);

Y luego:

    $alm->__SET('acronimo', $r["acronimo"]);
    $alm->__SET('categoria', $r["categoria"]);

Notas:

  1. Entre los corchetes después de $r debe haber exactamente los nombres de columnas como están en la base de datos.
  2. Para comprobar que hay datos en $r puedes hacer un print_r($r) en el cual verás un arreglo asociativo si tu consulta ha obtenido datos.

Nótese que PDO::FETCH_ASSOC es una de las formas que tiene PDO para obtener nuestros resultados. Lo que hace es crear un arreglo asociativo de nuestros resultados en los que la llave (key) es el nombre de cada columna del resultado y el valor es el contenido de dicha columna.

A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • El no entiende lo que le paso. Te comento el error de las lineas 56 y 57 ya desaparecio reconcoe tildes y ñ pero no el caracter especial "&". Y necesito que aparezca, aparece en blanco directamente cuanod selecciono una columna con "&". La conexion seria asi? $this->pdo = new PDO('mysql:host=localhost;dbname=deimos1;charset=UTF8', 'root', '');. El dato en codigo fuente intenta parsear el "&" fijate: pero sobra el ";" porque esa C deberia de ir junta es decir deberia visualizar "S&C" – Alberto Cepero de Andrés Apr 21 '17 at 10:51
  • No entiendo bien lo que dices del caracter especial `&`. ¿Significas que tienes columnas en tu bd que contienen ese carácter y no te las muestra? Si es eso edita la pregunta indicando la parte del código donde tratas de presentar el contenido de esas columnas. En cuanto a la conexión PDO, mejor edita tu pregunta poniendo la parte del código donde creas el objeto PDO pero **sin revelar nombre de usuario, contraseña y nombre de tu base de datos**, así podré decirte con exactitud lo del charset. – A. Cedano Apr 21 '17 at 10:56
  • vale ya e modificado todo el POST, gracias por tu ayuda. – Alberto Cepero de Andrés Apr 21 '17 at 11:15
  • Pero el problema esque la BBDD solo dispone de esas dos columnas y mi jefe me a comentado hace nada, que no quiere añadirle una tercera que contenga esos autoincrementable, asi que me parece a mi que nos acaba de fastidiar. Supongo que tu solucion no valdria. Me trae loco este tio – Alberto Cepero de Andrés Apr 21 '17 at 14:17
  • En ese caso, tendrías que usar redirecciones, y programar tu aplicación como se programan las API, usando urls amigables. En ese caso construirías las URL así por ejemplo: `index/editar/categoria/id/&CC` o, siendo más precisos y elegantes: `/categorias/editar/id/&CC`es una buena opción y no es tan difícil. Puedes recibir todo en index.php y hacer las redirecciones. Yo tengo construida así la API de una app usando un modelo MVC. Creo que tendrás que lanzarte por esa vía. – A. Cedano Apr 21 '17 at 14:35
  • Vale,entiendo por que lado me indicas por decirlo de alguna manera, esto se supone que luego debe de estar ingresado en el CMS Joomla no se si alguna vez lo has utilizado, lo que quiere decir que si debo de generarle una URL amigable, pero mi pregunta es, como ves recojo datos de una BBDD y ahora mismo tiene unicamente 7 registros pero podria contener más deberia de crear una url amigable por cada uno o solo con uno valdría? – Alberto Cepero de Andrés Apr 21 '17 at 17:55
  • @AlbertoCeperodeAndrés La cantidad de registros o la bd no es problema. Se trata de hacer lo mismo que ahora, pero de otro modo: usando por ejemplo lo que se llama diseño MVC (Modelo-Vista-Controlador). El Controlador sería tu index.php que recibe todas las entradas que llegan al servidor por URL, las distribuye enviándolas al modelo (datos) que los procesa y los envía a la Vista para mostrarlos. De esa forma el código queda organizado, optimizado, más comprensible y fácil de mantener. Es un poco largo para poder explicar en comentarios, en la red hay tutoriales muy buenos sobre esto. – A. Cedano Apr 21 '17 at 22:07