1

Edit: Pongo la salida de algunas variables que se ven en el codigo

$ventas:

array(18) { [0]=> array(20) 
            { ["id"]=> string(1) "9" 
            [0]=> string(1) "9" ["codigo"]=> string(5) "10001" 
            [1]=> string(5) "10001" ["id_cliente"]=> string(1) "1" 
            [2]=> string(1) "1" ["id_vendedor"]=> string(2) "17" 
            [3]=> string(2) "17" ["productos"]=> string(107) "[{"id":"61","descripcion":"Cera EDItada","cantidad":"1","stock":"68","precio":"10841.6","total":"10841.6"}]" 
            [4]=> string(107) "[{"id":"61","descripcion":"Cera EDItada","cantidad":"1","stock":"68","precio":"10841.6","total":"10841.6"}]" ["servicios"]=> string(160) "[{"descripcion":"Perfilado","precio":"250","id":"27"},{"descripcion":"Otros","precio":"299","id":"31"},{"descripcion":"Corte y barba","precio":"222","id":"32"}]" 
            [5]=> string(160) "[{"descripcion":"Perfilado","precio":"250","id":"27"},{"descripcion":"Otros","precio":"299","id":"31"},{"descripcion":"Corte y barba","precio":"222","id":"32"}]" ["precio_productos"]=> string(7) "10841.6" 
            [6]=> string(7) "10841.6" ["precio_servicios"]=> string(3) "771" 
            [7]=> string(3) "771" ["metodo_pago"]=> string(8) "Efectivo" 
            [8]=> string(8) "Efectivo" ["fecha"]=> string(19) "2020-01-01 16:40:15" 
            [9]=> string(19) "2020-01-01 16:40:15" 
         }

$usuarios

array(2) { [0]=> array(18)
         {["id"]=> string(1) "1" 
          [0]=> string(1) "1" ["nombre"]=> string(21) "Usuario Administrador" 
          [1]=> string(21) "Usuario Administrador" ["usuario"]=> string(6) "admin1" 
          [2]=> string(6) "admin1" ["password"]=> string(60) "$2a$07$hsdfhdhf..." 
          [3]=> string(60) "$2a$07$hsdfhdhfsdhfh27..." ["perfil"]=> string(8) "Especial" 
          [4]=> string(8) "Especial" ["foto"]=> string(34) "vistas/img/usuarios/admin1/772.png" 
          [5]=> string(34) "vistas/img/usuarios/admin1/772.png" ["estado"]=> string(1) "1"
          [6]=> string(1) "1" ["ultimo_login"]=> string(19) "2020-03-11 09:16:39" 
          [7]=> string(19) "2020-03-11 09:16:39" ["fecha"]=> string(19) "2020-03-11 09:16:39" 
          [8]=> string(19) "2020-03-11 09:16:39" 
        }

Estoy intentando recuperar en un arrays todas las ventas que realizo el usuario. Al array quiero agregarle los pares nombreUsuario => precioProductos

Al intentar el siguiente código, yo esperaba que el array arrayProdVendedores me traiga las 15 ventas que el usuario realizó, según lo que tengo en la base de datos. Pero la linea var_dump($arrayProdVendedores) me devuelve un array con un único elemento, que es la ultima venta realizada.

(Ya le hice var_dump a las variables usuarios y ventas y todo lo que traen es correcto.)

$ventas = ControladorVentas::ctrMostrarVentas($item,$valor);
$usuarios = ControladorUsuarios::ctrMostrarUsuarios($item,$valor);

$arrayVendedores = array();
$arrayProdVendedores = array();



foreach($ventas as $key => $valueVentas){

    foreach ($usuarios as $key => $valueUsuario){

        if($valueUsuario["id"] == $valueVentas["id_vendedor"]){


            #Capturamos nombres y precios en un mismo array
            $arrayProdVendedores[$valueUsuario["nombre"]] = $valueVentas["precio_productos"];

        } 


   }


}


var_dump($arrayProdVendedores);
Agustin G.
  • 1,946
  • 8
  • 25
  • 1
    Creo que podrías resolverlo de este modo: `$subArray=array ($valueVentas["precio_productos"], $valueVentas["precio_servicios"]); $arrayServVendedores[$valueUsuario["nombre"]] [] = $subArray;` He usado un `$subArray` para más claridad. La diferencia básica es esto `[]` en `$arrayServVendedores` que evitará que a cada paso se sobre-escriban los datos. Y, te recomiendo que uses nombres de variables menos kiloméeeeetricos. – A. Cedano Mar 11 '20 at 17:05
  • 1
    Jaja muchas gracias, en breve lo pruebo y les cuento como me fue. Me olvido fácil para qué sirven mis códigos, prefiero variables claras que ganar un code golf – Agustin G. Mar 11 '20 at 18:17
  • 2
    Mira la diferencia, si cambias `$arrayProdVendedores` por `$mVendors` o cambias `$valueUsuario` por `$mName` o cambias `$valueVentas` por `$mSales`, etc. Cuando veas las variables sabrás en seguida de qué se trata y si adoptas una convención de nombre en inglés las variables no sólo serán más cortas, sino que el código queda internacionalizado. Antes yo tenía la costumbre de indicar el tipo de dato que era, si array, si string, si entero... pero un día leí no sé donde que eso no servía para nada realmente y con el tiempo he comprendido que es cierto. De todos modos es una opción personal. – A. Cedano Mar 11 '20 at 18:28
  • 1
    Te agradezco, lo voy a tener en cuenta para las cosas que haga de aqui en adelante. Tu comentario/respuesta no me funciono, cabe aclarar que ya habia intentado ponerle [] al final del nombre del array y no tuve exito. De todas maneras no entiendo que estoy haciendo en ``$arrayServVendedores[$valueUsuario["nombre"]] [] = $subArray;``, en esa linea yo deberia guardarle solo el precio de los servicios, y segun lo que me pasaste, estoy guardando los dos. – Agustin G. Mar 11 '20 at 18:32
  • 1
    En el código original querías guardar los dos valores ¿no? En mi código es lo mismo, sólo que yo crée en `$subArray` un array con los dos valores y luego se lo paso al array final. Y el uso de `[]` es para que anide un sub-array en cada iteracción, solventando el problema principal que era que se sobre-escribía siempre el mismo índice. De todos modos leyendo tu pregunta da la impresión que mareas demasiado los datos y creo que todo el proceso podría simplificarse, pero para ayudarte en ese sentido habría que entender el contexto completo y tener una pequeña muestra de los datos. – A. Cedano Mar 11 '20 at 18:37
  • 1
    Por ejemplo, siendo que los datos vienen de una base de datos, ¿por qué esta lógica: `if($valueUsuario["id"] == $valueVentas["id_vendedor"]){` no se aplica en la consulta misma de la base de datos, de modo que no haya que traer datos para luego desecharlos (lo cual sólo se justificaría si usas todos los datos y lo que haces ahí es distribuirlos para diferentes usos)? Con esto quiero decir que desde la base de datos puedes incluso traer un objeto ordenado como quieras, incluso en forma de JSON. – A. Cedano Mar 11 '20 at 18:40
  • 1
    ahi edite el código, ahora quiero llenar un solo array con los pares ``nombre => precio``, espero que ahi te maree tanto, el problema sigue siendo el mismo – Agustin G. Mar 11 '20 at 18:43
  • 1
    Cuando hablo de *marear* los datos no me refiero a que metas todos los sub-arrays que quieras, sino al hecho de traer datos para luego filtrarlos con un `if` ¿por qué? y me refiero también al hecho de usar dos `foreach` para obtener unos resultados. No te digo que esté mal, sólo que viendo eso es posible que las cosas se puedan simplificar, pero como te dije, sin entender el contexto no es posible indicarte mejoras en ese sentido. Si no te quieres meter con la optimización, sugiero que muestres un pequeño dataset global para poder ayudarte pues hay que ver qué estructura tienen los datos. – A. Cedano Mar 11 '20 at 18:50
  • 1
    Ahi agregue cuales son los datos de cada una de las variables $ventas y $usuarios para darte un poco de contexto, pero no se si sera suficiente. Yo quiero recuperar todas las ventas (por eso cargo la variable $ventas) y luego todos los usuarios ( que serian los vendedores ), para poder calcular la cantidad de dinero que genero cada vendedor. – Agustin G. Mar 11 '20 at 19:03
  • 1
    Ufff no termino de aclararme. ¿Podrías facilitar una muestra de ambos arrays en forma PHP reproducible para hacer pruebas? Traté de adaptar el `var_dump` a array pero me genera cierta confusión. – A. Cedano Mar 11 '20 at 19:19
  • 1
    @A.Cedano hice algo muy poco ortodoxo, pero ahi puse al final de la pregunta, la salida completa de cada una de las variables, sin espacios, saltos de linea ni nada. Eso podra servir? – Agustin G. Mar 11 '20 at 19:22
  • A ver no. Por favor todos los datos sensibles bórralos. Yo quería una muestra en formato PHP para hacer pruebas ya que no termino de aclararme con el var_dump. – A. Cedano Mar 11 '20 at 19:26
  • Viendo el `var_dump` completo voy a hacer un muestreo, ahora vuelvo. Tienes una redundancia terrible en esos datos, debes pensar en optimizar muy seriamente. Se nota que hiciste en `fetch_array` sin más o algo así, porque tienes duplicados que da miedo... Ahora vuelvo... – A. Cedano Mar 11 '20 at 19:31
  • jaja tranquilo que las contraseñas son 1234, no es algo para produccion, es a modo de trabajo personal, pero gracias por la recomendacion y por el tiempo que te estas tomando. – Agustin G. Mar 11 '20 at 19:33
  • A ver una cosa. En el array de usuarios hay solamente dos usuarios, no entiendo entonces el dichoso `if` que función hace ¿? ¿Podrías explicar cuál es el planteamiento, porque no entiendo a qué se debe que quieras usar el array de usuarios para comparar y filtrar? – A. Cedano Mar 11 '20 at 19:52
  • El ``if`` es para comparar ``id`` de los usuarios con el ``id_vendedor`` de la venta, si son iguales, se agrega el par ``nombreUsuario => precioProductos`` al array – Agustin G. Mar 11 '20 at 19:57

5 Answers5

1

Solo agrega [] y con eso se soluciona tu problema.

$arrayProdVendedores[$valueUsuario["nombre"]][] = $valueVentas["precio_productos"];
$arrayServVendedores[$valueUsuario["nombre"]][] = $valueVentas["precio_servicios"];

Saludos

1

Acabo de probar esto

$valueUsuario["nombre"] = "Gerardo";
$valueVentas["precio_productos"] = 1;
$valueVentas["precio_servicios"] = 1;

for ($i=0; $i < 10; $i++) { 
    $arrayProdVendedores[$valueUsuario["nombre"]][] = $valueVentas["precio_productos"];
    $arrayServVendedores[$valueUsuario["nombre"]][] = $valueVentas["precio_servicios"];
    $valueVentas["precio_productos"] += 1;
    $valueVentas["precio_servicios"] += 1;
}

    print_r($arrayProdVendedores);

    print_r($arrayServVendedores);

Y me da como resultado esto y creo que es lo que buscas

Array
(
    [Gerardo] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 4
            [4] => 5
            [5] => 6
            [6] => 7
            [7] => 8
            [8] => 9
            [9] => 10
        )

)
Array
(
    [Gerardo] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 4
            [4] => 5
            [5] => 6
            [6] => 7
            [7] => 8
            [8] => 9
            [9] => 10
        )

)
1

yo creo que el problema viene porque este valor $valueUsuario["nombre"] es siempre el mismo entonces el lugar de añadir todos los registros los va machacando por eso sale siempre el ultimo. prueba intentado no generar un array asociativo o con la funcion push de php

aitorlv
  • 60
  • 8
  • 1
    En realidad no, porque la variable "ventas" me retorna muchos elementos, algunos tienen un id_vendedor y otros tiene uno diferente, ya que tengo ventas realizadas de ambos vendedores. La cosa es que por cada uno de ellos, me muestra la ultima venta en lugar de ir agregando, nisiquiera quiero que los sume, quiero que quede algo como ["oscar" => 200, "oscar" =>500, "agustin" => 400, "oscar" =>200] – Agustin G. Mar 11 '20 at 19:06
1

He sacado en limpio datos esenciales de cada array y el código funciona como te había dicho anteriormente.

Veamos:

$usuarios=
    array (
            array ("id"=>"1", "nombre"=>"Usuario Administrador"), 
            array ("id"=>"17","nombre"=>"Pepe")
        );

$ventas=array 
    (
        array (
                "id_vendedor"=>"17", 
                "precio_productos"=>"1",
                "precio_servicios"=>"10"                
            ),
        array (
                "id_vendedor"=>"17", 
                "precio_productos"=>"2",
                "precio_servicios"=>"20"                

            ),
        array (
                "id_vendedor"=>"18", 
                "precio_productos"=>"3",
                "precio_servicios"=>"30"                

            ),
        array (
                "id_vendedor"=>"17", 
                "precio_productos"=>"4",
                "precio_servicios"=>"40"                

            ),
    );

$mUser=array();
foreach($ventas as $key => $valueVentas){
    foreach ($usuarios as $key => $valueUsuario){
        if($valueUsuario["id"] == $valueVentas["id_vendedor"]){
            $subArray=array($valueVentas["precio_productos"], $valueVentas["precio_servicios"]);
            $mUser[$valueUsuario["nombre"]][]=$subArray;
        }
    }
}
var_dump($mUser); 

La salida es esta:

array(1) {
  ["Pepe"]=>
  array(3) {
    [0]=>
    array(2) {
      [0]=>
      string(1) "1"
      [1]=>
      string(2) "10"
    }
    [1]=>
    array(2) {
      [0]=>
      string(1) "2"
      [1]=>
      string(2) "20"
    }
    [2]=>
    array(2) {
      [0]=>
      string(1) "4"
      [1]=>
      string(2) "40"
    }
  }
}

He puesto datos ficticios. El vendedor Pepe tiene asociados los precios de productos y servicios. Si quieres ponerle un nombre a cada clave o bien organizar el resultado de otro modo me dices.

Aquí se ve más claro, poniendo nombres a cada clave:

$mUser=array();
foreach($ventas as $key => $valueVentas){
    foreach ($usuarios as $key => $valueUsuario){
        if($valueUsuario["id"] == $valueVentas["id_vendedor"]){
            $subArray=array("productos"=>$valueVentas["precio_productos"], "servicios"=>$valueVentas["precio_servicios"]);
            $mUser[$valueUsuario["nombre"]][]=$subArray;
        }
    }
}
var_dump($mUser);    

Salida:

array(1) {
  ["Pepe"]=>
  array(3) {
    [0]=>
    array(2) {
      ["productos"]=>
      string(1) "1"
      ["servicios"]=>
      string(2) "10"
    }
    [1]=>
    array(2) {
      ["productos"]=>
      string(1) "2"
      ["servicios"]=>
      string(2) "20"
    }
    [2]=>
    array(2) {
      ["productos"]=>
      string(1) "4"
      ["servicios"]=>
      string(2) "40"
    }
  }
}
A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • No por nada tienes 65.2K de reputacion. Alabado seas, gracias – Agustin G. Mar 11 '20 at 20:21
  • @Mani me alegro de que te haya servido. De todos modos revisa el tipo de `fetch` que estás aplicando para traer los datos. Tienes un montón de datos repetidos que lo único que hacen es sobrecargar la memoria. Eso puede ser problemático, sobre todo en conexiones concurrentes o en consultas que manejen muchos datos. Saludos. – A. Cedano Mar 11 '20 at 20:23
  • Lo hice siguiendo los pasos de un tutorial de udemi, en el modelo las unicas 3 lineas de la funcion mostrarVentas son: **1)** ``$stmt = Conexion::conectar()->prepare("SELECT * FROM $tabla ORDER BY id ASC");`` - **2)** ``$stmt -> execute();`` - **3)** ``return $stmt -> fetchAll();`` – Agustin G. Mar 11 '20 at 20:36
  • Luego, desde el controlador, unicamente tengo ``$respuesta = ModeloVentas::mdlMostrarVentas($tabla,$item,$valor);`` y un ``return $respuesta;``... tendria que aplicarle alguna funcion a esta ``$respuesta`` para que los datos se organicen de una forma mas optima? – Agustin G. Mar 11 '20 at 20:39
  • @Mani En la etapa **3)** que mencionas, puedes pasarle `PDO::FETCH_ASSOC` al método `fetchAll()` para que te traiga los datos únicamente como array asociativo. Por ejemplo: **`return $stmt -> fetchAll(PDO::FETCH_ASSOC);`** – A. Cedano Mar 11 '20 at 22:03
  • Muchas gracias, eso redujo a la mitad el tamaño de todos los resultados de consulta! Te agradezco mucho. No entendia porque me devolvia los datos duplicados, me guardare ese PDO::FETCH_ASSOC para siempre. – Agustin G. Mar 11 '20 at 22:20
  • @Mani de nada. Si quieres más info sobre esto, te dejo [este enlace](https://es.stackoverflow.com/a/184343/29967). Es una respuesta más documentada y con enlaces al Manual de PHP por si quieres ampliar conceptos. – A. Cedano Mar 11 '20 at 22:26
0

El problema es que necesitas un array, no lo estás inicializando y solo estás agregando un valor.

En versiones anteriores de PHP podías agregar elementos a un array no definido sin mayor problema, en versiones recientes ya no es posible.

$array[] = 'algo'; // En versiones anteriores funcionaba

$array = []; // Ahora debes inicializar
$array[] = 'algo'; // Solo así puedes agregar elementos

Solución a tu problema:

$ventas = ControladorVentas::ctrMostrarVentas($item,$valor);
$usuarios = ControladorUsuarios::ctrMostrarUsuarios($item,$valor);

$arrayVendedores = array();
$arrayProdVendedores = array();

foreach($ventas as $key => $valueVentas){

    foreach ($usuarios as $key => $valueUsuario){

        if($valueUsuario["id"] == $valueVentas["id_vendedor"]){
            // Verificar que existe el array
            if(!isset($arrayProdVendedores[$valueUsuario["nombre"]])) {
                // No existe, entonces se crea
                $arrayProdVendedores[$valueUsuario["nombre"]] = [];
            }

            #Capturamos nombres y precios en un mismo array
            // Con los corchetes al final agregas un nuevo elemento
            $arrayProdVendedores[$valueUsuario["nombre"]][] = $valueVentas["precio_productos"];

        } 
   }
}
Triby
  • 23,274
  • 3
  • 13
  • 35