¿Por qué la paginación de Instagram devuelve la misma página una y otra vez?

5 minutos de lectura

avatar de usuario
guillermo

El código

Creé una clase de PHP para comunicarme con la API de Instagram. Estoy usando una función privada llamada api_request (que se muestra a continuación) para comunicarse con la API de Instagram:

private function api_request( $request = null ) {

    if ( is_null( $request ) ) {
        $request = $this->request["httpRequest"];
    }
    $body = wp_remote_retrieve_body( wp_remote_get( $request, array(
                "timeout" => 10,
                "content-type" => "application/json"
            )
        )
    );

    try {
        $response = json_decode( $body, true );
        $this->data["pagination"] = $response["pagination"]["next_url"];
        $this->data["response"] = $response["data"];

        $this->setup_data( $this->data );

    } catch ( Exception $ex ) {
        $this->data = null;
    }
}

Estas dos líneas de código…

$this->data["pagination"] = $response["pagination"]["next_url"];
$this->data["response"] = $response["data"];

… configura mis datos dentro de esta matriz:

private $data = array (
    "response"      => null,
    "pagination"    => null,
    "photos"        => array()
);

El problema

Siempre que solicito la siguiente página, con la siguiente función:

public function pagination_query() {
    $this->api_request( $this->data["pagination"] );
    $output = json_encode( $this->data["photos"] );

    return $output;
}

Instagram me da la primera página, una y otra y otra vez. ¿Alguna idea de cuál es el problema aquí?

Actualización #1

Me di cuenta de eso porque mi setup_data función (usada en api_request función) empuja mis objetos fotográficos al final de mi $this->data["photos"] formación:

private function setup_data( $data ) {

    foreach ( $data["response"] as $obj ) {

        /* code that parses the api, goes here */


        /* pushes new object onto photo stack */
        array_push( $this->data["photos"], $new_obj );
    }
}

…es necesario crear una matriz vacía, al solicitar una nueva página:

public function pagination_query() {

    $this->data["photos"] = array(); // kicks out old photo objects

    $this->api_request( $this->data["pagination"] );
    $output = json_encode( $this->data["photos"] );

    return $output;
}

Puedo recuperar la segunda página, pero todas las posteriores pagination_query las llamadas solo devuelven la segunda página. ¿Alguna idea sobre que podría ir mal?

Actualización #2

Descubrí que usando un while declaración, para hacer la api_request la función se llama a sí misma, me permite recuperar página tras página muy bien:

private function api_request( $request = null ) {

    if ( is_null( $request ) ) {
        $request = $this->request["httpRequest"];
    }

    $body = wp_remote_retrieve_body( wp_remote_get( $request, array(
                "timeout" => 18,
                "content-type" => "application/json"
            )
        )
    );

    try {
        $response = json_decode( $body, true );

        $this->data["response"] = $response["data"];
        $this->data["next_page"] = $response["pagination"]["next_url"];

        $this->setup_data( $this->data );

        // while state returns page after page just fine
        while ( count( $this->data["photos"] ) < 80 ) {
            $this-> api_request( $this->data["next_page"] );
        }

    } catch ( Exception $ex ) {
        $this->data = null;
    }
}

Sin embargo, esto no soluciona mi pagination_query funciona y parece como si mi try-catch block está creando un cierre y no estoy muy seguro de qué hacer con esto.

  • cual es la salida del $response formación

    – Michael St Clair

    14 de junio de 2015 a las 14:31

  • Hola, @MichaelStClair, puedes encontrar la estructura del sobre de respuesta aquí: Puntos finales de la API de Instagram

    – Guillermo

    14 de junio de 2015 a las 14:41

  • imprimir $response["pagination"]["next_url"]; y ver si hay incluso un valor allí

    – Michael St Clair

    14 de junio de 2015 a las 14:44

  • @MichaelStClair También lo sospeché, pero devuelve el parámetro pagination.next_url del json, como se esperaba.

    – Guillermo

    14 de junio de 2015 a las 14:53

  • ¿Necesitas el $this-> delante de él para asignar ese valor a la matriz? ¿Qué pasa si quitas eso?

    – Michael St Clair

    14 de junio de 2015 a las 14:56

En su primer fragmento de código tiene:

    $this->data["response"] = $response["data"];
    $this->data["next_page"] = $response["pagination"]["next_url"];

Tenga en cuenta dos claves: response y next_page

Luego, en tu segundo fragmento tienes:

    $this->data["pagination"] = $response["pagination"]["next_url"];
    $this->data["response"] = $response["data"];

Ahora next_page es pagination

ahora si usas

$this->api_request( $this->data["pagination"] );

pero estas usando $this->data["next_page"] = $response["pagination"]["next_url"]; por supuesto que no obtendrá los resultados correctos.

En cualquier caso, intente var_dump el contenido de su $ solicitud:

public function pagination_query() {
    var_dump($this->data["pagination"]);
    $this->api_request( $this->data["pagination"] );
    $output = json_encode( $this->data["photos"] );

    return $output;
}

Si tiene un debbugger, también verifique dentro de api_request, cuál es la URL pasada cada vez

  • Gracias por señalar eso. Actualicé el nombre de la clave para mayor claridad y olvidé actualizarlo en mi pregunta (lo siento). En lo que respecta a la var dumpcambié el return en mi pagination_query función a return $this->data["next_page"] y devuelve el enlace a la segunda página una y otra vez. La única pregunta que estoy tratando de resolver es por qué todos los subsiguientes pagination_query llamadas devuelven el enlace desde la primera vez que se llamó?

    – Guillermo

    14/06/2015 a las 23:36

  • ¿Crees algo, dentro de mi try-catch bloque, ¿haría que las variables persistieran o no se actualizaran?

    – Guillermo

    14/06/2015 a las 23:40

  • sí, si algo sale mal en el intento… captura, no obtendrás la next_url correctamente

    – dinámico

    15 de junio de 2015 a las 7:03

  • se debe agregar una url para referencia api

    usuario1817927

    19/06/2015 a las 20:50

  • oye @rubenrp81, ¿podrías explicar a qué te refieres?

    – Guillermo

    20 de junio de 2015 a las 11:35

avatar de usuario
guillermo

He agregado las siguientes líneas de código al try bloque de mi try...catch declaración para devolver varias páginas sucesivas a la vez:

while ( count( $this->data["photos"] ) < 160 ) {
    $this-> api_request( $this->data["next_page"] );
}

Esto esencialmente dice api_request llamarse hasta mi $this->data["next_page"] La matriz se rellena con 160 “gramos”.

Esto me permite recuperar un total de 320 gramos de la API de Instagram: 160 gramos cuando api_request se llama después de cargar la página y otros 160 desde mi primera pagination_query llamar.

Esta no es una solución ideal como segundo pagination_query llamar todavía devuelve los mismos datos de mi primera pagination_query llamar pero tendrá que hacer por el momento.

Actualizar

La solución anterior es un truco. Si alguien puede averiguar por qué mi pagination_query El método todavía no funciona, sería muy apreciado.

¿Ha sido útil esta solución?