I don't want to have image IDs in the source code of the posts, so I fetch them using the_content filter - the auxiliary function that does the query is as below. It works fine when I get up to 10 or 11 IDs, and if there are more IDs, they won't appear in the result of the query. Querying by batches of 10 works, but it is much longer (about 30 sec for 700 images!). If I increase the size of the batch, without changing anything else in my function, the database starts to drop some results.

Is there a reason for it? What am I doing wrong?

I have only a couple of weeks experience in php/WP programming, please don't judge the code too harshly.

The query is based on this answer. An example of (a very convolutive) structure of wp_attachment_metadata, which makes LIKE inevitable, is here.

/* get images metas given their names and folders */
function get_images_meta_id( $filenames ) {
    error_log( 'metas started ' );

    $an_upload_dir = trailingslashit(wp_upload_dir()['url']);
    $an_upload_dir_len = strlen($an_upload_dir);

    $filenames_as_params = array();
    $prev_fn = '';
    foreach ( $filenames as $fn ) {
        if ((strpos($fn, $an_upload_dir) !== 0) or ($fn === $prev_fn)) {
        $prev_fn = $fn;
        array_push($filenames_as_params, array(
                'value'   => '"' . substr($fn, $an_upload_dir_len) . '"',
                'compare' => 'LIKE',
                'key'     => '_wp_attachment_metadata',

    $metas = array();
    $counter = 0;
    while($counter < count($filenames_as_params)) {
        $meta_query_array = array_slice($filenames_as_params, $counter, 10);
        $counter += 10;
        $meta_query_array['relation'] = 'OR';
        $query_args = array(
            'post_type'   => 'attachment',
            'post_status' => 'inherit',
            'fields'      => 'ids',
            'meta_query'  => $meta_query_array

        $query = new WP_Query( $query_args ); 

        if ( $query->have_posts() ) {
            foreach ( $query->posts as $post_id ) {
                $meta = wp_get_attachment_metadata( $post_id );
                $meta['attachment_id'] = $post_id;
                $metas[$meta['file']] = $meta;
    error_log( 'metas done ' );
    return $metas;

It returns 10, because that is usually the default specified at your site "read" settings (IIRC) and is used obviously explicitly for the front end, but also as default for the number of posts returned by wp_query. What you are looking for is the number_of_posts (don't trust me, check the docs) argument for the query.

Aside, not sure what is it you are trying to do, but using LIKE will make your queries slow. Whatever you are trying to do, there must be a better way (unless this code will run only once, and then maybe performance is not an issue)

Your Answer

