elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Security Series.XSS. [Cross Site Scripting]


+  Foro de elhacker.net
|-+  Programación
| |-+  Desarrollo Web
| | |-+  PHP (Moderador: #!drvy)
| | | |-+  [resuelto] imprimir lista con datos de db
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [resuelto] imprimir lista con datos de db  (Leído 3,086 veces)
gAb1


Desconectado Desconectado

Mensajes: 731


Ver Perfil
[resuelto] imprimir lista con datos de db
« en: 7 Octubre 2014, 02:52 am »

Hola buenas! Estoy haciendo una lista que imprima informacion de varias tablas de una base de datos mysql. Estas son las tablas:

- account_type: tiene dos columnas: type (varchar, usada en la consulta) y bonus (int, imprimida en la lista).
- friends: de aqui necesito las columnas total y cashed_month1-12 (todas int)
- members: varias columnas: id y acc_type (usadas en la consulta), las demás columnas tambien son seleccionadas y se deberían de imprimir normal.

Lo que el siguiente script debería hacer sería lo siguiente:

Seleccionar de estas 3 tablas: friends.*, members.*, y account_type.* pero con la unica condición de INNER JOIN account_type ON account_type.type = members.acc_type

Código
  1. if(isset($_GET['id'], $_SESSION['user_id'])) {
  2.  
  3. /* prepare statement */
  4. if ($stmt = $mysqli->prepare("SELECT COUNT(*) rowCount FROM friends WHERE friendID = ? AND userID = ?")) {
  5. $stmt->bind_param('ii', $_GET['id'], $_SESSION['user_id']);
  6. $stmt->execute();
  7. /* bind variables to prepared statement */
  8. $stmt->bind_result($rowCount);
  9.  
  10. /* fetch values */
  11. if($stmt->fetch()) {
  12. if ($rowCount > 0) {
  13.  
  14. $stmt->close();
  15.  
  16. if ($stmt = $mysqli->prepare("SELECT members.*, account_type.* FROM members INNER JOIN account_type ON account_type.type = members.acc_type
  17.                                                                                                WHERE members.acc_type = ?")) {
  18. $stmt->bind_param('s', $_SESSION['acc_type']);
  19. $stmt->execute();
  20.  
  21. $result = $stmt->get_result();
  22. $row = $result->fetch_array();
  23.  
  24.  
  25. if ($row['status'] == 1) {
  26. $status = 'Activa';
  27. } elseif ($row['status'] == 0) {
  28. $status = 'No Activa';
  29. }
  30.  
  31. echo '<p>La cuenta esta ' . $status . ';
  32.  
  33. $monthNames = array("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre");
  34. $paid = array(); //Placeholder for paid months.
  35.  
  36. for ($i = 1; $i < 13; $i++) {
  37. $month = 'month' . $i;
  38. $cashed_month = 'cashed_month' . $i;
  39. if($row[$month] == 1) {
  40. $paid[] = 'Pagado';
  41. $bonus[] = $row['bonus'] . '';
  42. } else {
  43. $paid[] = 'No Pagado';
  44. $bonus[] = 'n/a';
  45. }
  46. if ($row[$cashed_month] == 1) {
  47. $cashed[] = 'Si';
  48. } elseif ($row[$month] == 1) {
  49. $cashed[] = 'No';
  50. } else {
  51. $cashed[] = 'n/a';
  52. }
  53. }
  54.  
  55. //Now make the HTML list
  56.  
  57. foreach($monthNames as $key => $month) {
  58. echo '
  59. <div class="list">
  60. <ul>
  61. <li><a class="month">' . $month . '</a></li>
  62. <li><a class="status">' . $paid[$key] .'</a></li>
  63. <li><a class="bonus">' . $bonus[$key] . '</a></li>
  64. <li><a class="cashed">' . $cashed[$key] . '</a></li>
  65. </ul>
  66. </div>';
  67. }
  68.  
  69. echo '<div class="clear"></div>';
  70.  
  71. echo '<p>Total recibido para ' . date('Y') . ': ' . $row['total'] . '</p>';
  72.  
  73. echo '<a href="/friend">Volver</a>';
  74.  
  75. } else echo $mysqli->error;
  76.  
  77. } else{
  78. echo $_SESSION['username'], ', no estás autorizado para ver la información de este socio ya que no es tu amigo...';
  79. }
  80. }
  81. /* close statement */
  82. $stmt->close();
  83. } else echo $mysqli->error;
  84. /* close connection */
  85. $mysqli->close();
  86. }
  87.  

Pero no encuentro la manera de agregar esta tercera tabla sin necesidad de condicion, ya que si hago otro inner join con la tercera tabla, no funciona como es debido:

Por ejemplo, necesito trabajar con $row['bonus'] (tabla account_type) pero que sea el del usuario actual, no del otro (friendID). Si ambas cuentas (friendID y userID) tienen el mismo tipo de cuenta (acc_type) todo funciona, pero no todos las cuentas son iguales, entonces si cambio el acc_type del usuario logueado no funciona nada, es como si solamente se muestra información si ambas cuentas tienen el mismo tipo, y eso no debería ser así. Por eso no puedo juntar esta tercera tabla.

¿Es posible selecionar una tabla más sin ninguna condicion? Simplemente cogiendo toda la informacion sin más y en la misma sentencia preparada.

Gracias!


« Última modificación: 7 Octubre 2014, 23:41 pm por gAb1 » En línea

MinusFour
Moderador Global
***
Desconectado Desconectado

Mensajes: 5.529


I'm fourth.


Ver Perfil WWW
Re: imprimir lista con datos de db
« Respuesta #1 en: 7 Octubre 2014, 18:01 pm »

No debería darte problemas si agregas un INNER JOIN sin ninguna condicion.

Código
  1. SELECT * FROM tabla INNER JOIN tabla2

Que viene siendo lo mismo que: (en MySQL)

Código
  1. SELECT * FROM tabla CROSS JOIN tabla2


En línea

gAb1


Desconectado Desconectado

Mensajes: 731


Ver Perfil
Re: imprimir lista con datos de db
« Respuesta #2 en: 7 Octubre 2014, 18:09 pm »

Actualmente estoy usando INNER JOIN. Entonces para MySQL debo usar CROSS JOIN?

Aunque ahora que lo pienso bien creo que necesito condiciones para las columnas y de que ID debo coger cada columna:

1º from members.status (y otras columnas como name, month1-12 and photo) where members.id = $_GET['id']
2º from account_type.type necesito que compare con members.acc_type pero especificando where members.id = $_SESSION['user_id'] y solo de esa id.
3º from friends.cashed_month1-12 (y la columna total que debería incluirse sin problemas) where friends.friendID = $_GET['id']

Necesito una consulta que haga todo eso, pero mi conocimiento en sql es bastante limitado. He estado intentandolo con:

Código
  1. SELECT friends.*, members.*, account_type.* FROM members INNER JOIN friends ON friends.friendID = members.id
  2.                                                              INNER JOIN account_type ON account_type.type = members.acc_type
  3.                                                              WHERE friends.friendID = ? AND members.acc_type = ?")) {
  4. $stmt->bind_param('is', $_GET['id'], $_SESSION['acc_type'];

Y obviamente no funciona... :(

Edito: se me olvido cambiar el bind_param de otra prueba. Y el problema no era hacer un JOIN para la tercera tabla. Asi que debo hacer un JOIN, pero el problema esque mi consulta esta mal.
« Última modificación: 7 Octubre 2014, 18:29 pm por gAb1 » En línea

MinusFour
Moderador Global
***
Desconectado Desconectado

Mensajes: 5.529


I'm fourth.


Ver Perfil WWW
Re: imprimir lista con datos de db
« Respuesta #3 en: 7 Octubre 2014, 18:34 pm »

Sería mejor que describieras que quieres hacer con tus tablas. Tampoco entiendo muy bien tus tablas o sus relaciones.

Pon un Describe de las tablas;

Código
  1. DESCRIBE friends;
En línea

gAb1


Desconectado Desconectado

Mensajes: 731


Ver Perfil
Re: imprimir lista con datos de db
« Respuesta #4 en: 7 Octubre 2014, 19:11 pm »

La idea era hacer un sistema RBAC, pero en realidad solo necesito 1 columna para un permiso entonces lo hice asi: account_type -> type y bonus. Cada cuenta puede ser de un tipo u otro, por lo que en la tabla miembros tengo una columna llamada acc_type que coincide con el valor de account_type.type, entonces la cuenta tiene los privilegios de ese tipo.

Y las columnas month1 a 12, 1 quiere decir si ha pagado ese mes y 0 que no lo ha pagado. Tambien cada cuenta tiene un status, 1 activa y 0 no activa.

La tabla friends tiene el id de la cuenta que es amiga de otra cuenta (friendID es amigo de UserID) las otras columnas, total: el total acumulado para userID y cashed_month1 a 12, 1: ha recibido el bonus para ese mes y 0: no no lo ha recibido, tambien para userID

Nunca he hecho eso de DESCRIBE, no se que es.

Lo que no entiendo es porque
Código
  1. INNER JOIN account_type ON account_type.TYPE = members.acc_type WHERE members.acc_type = $_SESSION['acc_type']
no funciona si $_GET['id'] (friendID) no tiene el mismo tipo de cuenta....

¿Ves alguna relación entre members.acc_type (de la cuenta logueada) con members.acc_type (friendID)?

Es muy extraño la verdad, debe ser esa consulta que esta mal hecha, pero no veo cual es el fallo...

Si no coinciden ambas devuelve NULL  :huh:

Así es como lo tengo ahora:

Código
  1. if ($stmt = $mysqli->prepare("SELECT friends.*, members.*, account_type.* FROM members INNER JOIN friends ON friends.friendID = members.id
  2.                                                                               INNER JOIN account_type ON account_type.type = members.acc_type
  3.       WHERE friends.friendID = ? AND members.acc_type = ?")) {
  4. $stmt->bind_param('is', $_GET['id'], $_SESSION['acc_type']);

¿Tal vez si uso LEFT o RIGHT devolverá todo lo demás menos el match entre los dos ids?
« Última modificación: 7 Octubre 2014, 19:14 pm por gAb1 » En línea

MinusFour
Moderador Global
***
Desconectado Desconectado

Mensajes: 5.529


I'm fourth.


Ver Perfil WWW
Re: imprimir lista con datos de db
« Respuesta #5 en: 7 Octubre 2014, 19:28 pm »

Yo la verdad es que no tengo ni idea de como es tu base de datos. Es muy ambigua tu descripcion (al menos para mi).

Si no puedes pegar el describe, entonces pon la estructura de tu base de datos.
En línea

gAb1


Desconectado Desconectado

Mensajes: 731


Ver Perfil
Re: imprimir lista con datos de db
« Respuesta #6 en: 7 Octubre 2014, 19:48 pm »

Aquí he pegado la estructura: http://pastebin.com/sX8BAECm

Gracias!
En línea

MinusFour
Moderador Global
***
Desconectado Desconectado

Mensajes: 5.529


I'm fourth.


Ver Perfil WWW
Re: imprimir lista con datos de db
« Respuesta #7 en: 7 Octubre 2014, 20:33 pm »

Vamos por partes:

Código
  1. SELECT members.*, account_type.*
  2. FROM members
  3. INNER JOIN account_type ON `members`.`acc_type` = `account_type`.`type`

Debería regresar un join 1 a 1 con el account_type de members para obtener el bonus (me imagino).

Ahora para la tabla friends, no estoy muy seguro de la estructura de la tabla, pero quiero creer que hay varios friendId para userId. Entonces, si haces un inner join con friends por userid:

Código
  1. SELECT members.*, account_type.*, friends.*
  2. FROM members
  3. INNER JOIN account_type ON `members`.`acc_type` = `account_type`.`type`
  4. INNER JOIN friends ON friends.userID = members.id

Te debería devolver todos los registros unidos con todos los friends por ejemplo:

John - Mike
John - Joe
John - Mark
John - Luke

Entonces, el resultado quedaria como:

John [columnas de members] [columnas de account_type] Mike [columnas de friend]
John [columnas de members] [columnas de account_type] Joe [columnas de friend]
John [columnas de members] [columnas de account_type] Mark [columnas de friend]
John [columnas de members] [columnas de account_type] Luke [columnas de friend]

Las columnas de account_type estan ligadas a la informacion de John, no de Mike, Joe, Mark o Luke.

Ahora lo que puedes hacer para traerte la informacion relevante de Mike, Joe, Mark y Luke es hacer otro inner join.

Código
  1. SELECT members.*, account_type.*, friends.*, membersF.*
  2. FROM members
  3. INNER JOIN account_type ON `members`.`acc_type` = `account_type`.`type`
  4. INNER JOIN friends ON friends.userID = members.id
  5. INNER JOIN members AS membersF ON membersF.id = friends.friendID

Esto me devuelve la informacion del amigo en membersF.* ahora si necesitas sacar el bonus por account_type:

Código
  1. SELECT members.*, account_type.*, friends.*, membersF.*, acctypeF.*
  2. FROM members
  3. INNER JOIN account_type ON `members`.`acc_type` = `account_type`.`type`
  4. INNER JOIN friends ON friends.userID = members.id
  5. INNER JOIN members AS membersF ON membersF.id = friends.friendID
  6. INNER JOIN account_type AS acctypeF ON `membersF`.`acc_type` = `acctypeF`.`type`

Y los datos ahi estan en acctypeF.*

En este caso tienes que tener cuidado con los * y fetch_assoc porque members, membersF y account_type, acctypeF tienen los mismos campos.
En línea

gAb1


Desconectado Desconectado

Mensajes: 731


Ver Perfil
Re: imprimir lista con datos de db
« Respuesta #8 en: 7 Octubre 2014, 21:12 pm »

Vale, eso tiene mucho más sentido :)

Solo una cosa, la idea es sacar la informacion del amigo que el usuario haga click, no de todos a la vez. Al principio del archivo .php tengo un script para imprimir la lista de amigos del usuario:

Código
  1. if(empty($_GET)) {
  2.    // imprimir lista de amigos
  3. }

Ahí si que hago:
Código
  1. SELECT members.*, friends.*
  2. FROM friends
  3. INNER JOIN members ON members.id = friends.friendID
  4. WHERE friends.userID = ? /* mi id $_SESSION */

Y con eso hago una lista con todos los amigos, y en el nombre imprimido añado un url que envia a la misma página pero con el id del amigo:

Código
  1. echo '
  2. <div class="list">
  3. <ul>
  4. <li><a class="name" href="friend?id=' . $row['id'] . '">'.$row['name'].'</a></li>
  5. <li><a class="subscription">' . $status . '</a></li>
  6. <li><a class="totalbonus">' . $row['total'] . '€</a></li>
  7. </ul>
  8. </div>
  9. ';
  10.  

Entonces ahora estoy atascado en el if que obtiene $_GET['id'] y muestra otra tabla con la información del amigo, y ese es el código que pegué en el primer mensaje, en la misma pagina.php se muestra la lista de amigos y en el nombre hay un link que muestra la información de ese usuario.

No estoy seguro pero voy a probar con
Código
  1. SELECT members.*, account_type.*, friends.*, membersF.*
  2. FROM members
  3. INNER JOIN account_type ON `members`.`acc_type` = `account_type`.`type`
  4. INNER JOIN friends ON friends.userID = members.id
  5. INNER JOIN members AS membersF ON membersF.id = friends.friendID
  6. WHERE `members`.`acc_type` = $_SESSION['acc_type']
  7. AND friends.userID = $_SESSION['user_id']
  8. AND membersF.id = $_GET['id']

1º Devolverá el tipo de cuenta para el usuario conectado y así poder obtener el bonus del usuario conectado solo.
2º Aquí ¿devolverá las columnas total y cashed_month1 a 12? para saber si ya ha recibido el bonus de cada mes o no.
3º Aquí devolverá la información relevante para el amigo.

Más o menos me voy enterando de como funciona.

Lo que no me queda claro es WHERE <-- aquí que tengo que poner? la tabla.columna antes del = o de despues?

Gracias!

Edito: Funciona perfecto! Muchas gracias ^^
« Última modificación: 7 Octubre 2014, 23:41 pm por gAb1 » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
como imprimir la lista de cd de formato mp3
Software
chicharron 1 2,333 Último mensaje 25 Noviembre 2004, 02:34 am
por kyokorn
Problemas con imprimir un arbol binario de busqueda junto a una lista simple!!
Programación C/C++
01munrra 1 5,349 Último mensaje 23 Junio 2011, 02:24 am
por BlackZeroX
elimiar datos de una lista de base de datos
PHP
charles babbage 4 2,857 Último mensaje 4 Octubre 2012, 19:51 pm
por arodriguez
Cómo imprimir una lista de vectores
Java
reygecko 1 2,035 Último mensaje 8 Enero 2013, 13:06 pm
por reygecko
Imprimir una lista enlazada de forma ascendente
Programación C/C++
maunk 1 4,413 Último mensaje 3 Febrero 2014, 09:29 am
por eferion
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines