fopen() devuelve Exception por demasiadas peticiones seguidas, ¿cómo evitarlo?

  • Autor Autor adruiz
  • Fecha de inicio Fecha de inicio
adruiz

adruiz

Gamma
Verificación en dos pasos activada
Verificado por Whatsapp
Ocurre que estoy programando un plugin para Wordpress (planteo el problema aquí porque es más una cuestión de PHP que de WP), con el cual cada vez que implemento un shortcode se llama a una función que tiene un fopen apuntando a la API de AWS. Esta función devuelve unos valores u otros dependiendo del contenido del shortcode.

¿Qué ocurre entonces? Que si hay varios shortcodes en el post, el código ejecuta el fopen muy seguido y en un punto falla, dando un Exception error.

Mi solución (provisional) es usar dos usleep de medio segundo, uno después de llamar a la función y otro si el fopen da error, para luego volver a definirlo. Sería algo como esto:
PHP:
function getItem(){
    // $host, $uriPath, $stream ...
    $fp = @fopen('https://'.$host.$uriPath, 'rb', false, $stream);

    if(!$fp) {
        usleep(500000);
        $fp = @fopen('https://'.$host.$uriPath, 'rb', false, $stream);

        if(!$fp) throw new Exception("Exception Occured");
    }
    // ...
}

getItem();
usleep(500000);

Como posible solución, funciona, pero me gustaría encontrar una solución más elegante. ¿Alguna sugerencia?

¡Gracias!
 
puedes probar a utilizar file_get_contents
Tiene su miga, tendría que ver si la API de AWS me aceptaría este método, son maneras distintas de obtener los datos.

Los datos después los recopilo mediante un stream_get_contents, que entiendo que vendría a ser similar a lo que hace get_file_contents. Otra cosa que no sé es si me convendría realizar un fclose() cada vez que obtengo los datos.

Seguiré indagando, me has dado una pista de por donde tirar. Gracias 👍
 
veo tu código que no esta utilizando fclose y es muy probable que ese sea tu inconveniente.
Si estas enviando a una variable el fopen, este fichero no puede utilizarse dependiendo del parámetro enviado (lectura/escritura/default) hasta que el archivo sea cerrado. (Sino mal recuerdo generas un archivo temporal y mientras no lo cierres te llenas de basura)
No puedo decir mucho, utilize mas que todo fopen en c# para ficheros, en PHP utilizo mas lo que es curl y te pide cerrar la consulta.

Te recomendaría utilizar fclose cuando termines tu consulta de fopen, sea fichero o URL, una vez obtenida en una variable finaliza con fclose.

En todo caso, podrías compartir tu exception error así podríamos darte una mejor respuesta.
Disculpa si no fui claro, soy algo malo enseñando.
----------------------------
Agrego: estas intentando obtener información de una web o similar?
Puedes utilizar métodos recursivos para obtener la información dentro de un while o función en caso genere una excepción.
 
veo tu código que no esta utilizando fclose y es muy probable que ese sea tu inconveniente.
Si estas enviando a una variable el fopen, este fichero no puede utilizarse dependiendo del parámetro enviado (lectura/escritura/default) hasta que el archivo sea cerrado. (Sino mal recuerdo generas un archivo temporal y mientras no lo cierres te llenas de basura)
No puedo decir mucho, utilize mas que todo fopen en c# para ficheros, en PHP utilizo mas lo que es curl y te pide cerrar la consulta.

Te recomendaría utilizar fclose cuando termines tu consulta de fopen, sea fichero o URL, una vez obtenida en una variable finaliza con fclose.

En todo caso, podrías compartir tu exception error así podríamos darte una mejor respuesta.
Disculpa si no fui claro, soy algo malo enseñando.
----------------------------
Agrego: estas intentando obtener información de una web o similar?
Puedes utilizar métodos recursivos para obtener la información dentro de un while o función en caso genere una excepción.
Al final he dado con una solución parcial, fclose sin entender por qué, no funcionaba como debía.

El problema era el nº de peticiones y el límite de la API, que solo acepta una cantidad de peticiones por segundo y por lo visto me excedía.

En lugar fopen he acabado usando una función similar de Wordpress, wp_safe_remote_post(). Aunque puntualmente sigue fallando pero ya no mostraré más errores y en su lugar le paso un return false. De todos modos voy a tener que replantear un huevo la programación de esto, no es muy práctico hacer una petición a la API por cada item, cuando es posible pasar todos los items en una sola petición.

Gracias a los igualmente 👍
 
@adruiz ¿no podrías usar algún tipo de caché para limitar la cantidad de peticiones que se realizan?
 
Atrás
Arriba