markjaquith / feedback

Ask @markjaquith anything!
42 stars 4 forks source link

Best method to get contents of a local file in WordPress #33

Closed MickeyKay closed 9 years ago

MickeyKay commented 9 years ago

Hi there,

I'm wondering the best method to get the contents of a local file - say a something like versions.json - in a WordPress plugin or theme.

My searching has turned up several possible solutions, and I'm wondering if you can help elucidate the benefits/drawbacks of each:

  1. Output buffering
ob_start();
include $my_file_path;
$contents = ob_get_clean();

This method seems the most straightforward to me, but doesn't work within any particular WordPress API. The reason I include it is that it is so simple and seemingly easier to setup then the two WordPress API's listed below. Are there drawbacks I'm not seeing though?

  1. wp_remote_fopen() [HTTP API]
$contents = wp_remote_fopen( $my_file_path );

The HTTP API is really well documented and seems to be the suggested solution for retrieving remote files, however I can't find anything about how appropriate it is when getting the contents of a local file. Furthermore, should I be using wp_remote_fopen()? wp_remote_get()? Another one? When using the HTTP API in the past, I've run into timeout issues, and I'm wondering if there's not a better way since I want to access a local file, not a remote one.

  1. get_contents() [Filesystem API]

Honestly, I haven't tried this one as it seems pretty complicated (credentials, initializing, etc) just to get the contents of a local file (hence my preference for option number 1). Am I missing something?

Thanks Mark!

JDGrimes commented 9 years ago

My take is that the Filesystem API is more about securely writing files, reading them isn't really the issue it is trying to solve. What's wrong with file_get_contents()? I'd say that's the way to do it. I don't think WordPress provides (or needs to provide) a special API just for reading local files, PHP already makes that trivial.

MickeyKay commented 9 years ago

Thanks JD. I'm right there with you. file_get_contents() was the clear choice, however in my research I came across a ton of threads in which folks were having trouble with various servers not allowing it to run (https://www.google.com/search?q=wordpress%20%22file_get_contents%22&rct=j). Furthermore, I couldn't find anything definitive stating once and for all that file_get_contents() is the recommended method for accessing local files. There's tons of info on wp_remote_get() being the method of choice for remote files, however I couldn't turn up anything clearly stating the best practices for getting local file contents in WP.

In lieu of file_get_contents(), I'm using the following:

function get_local_file_contents( $file_path ) {
    ob_start();
    include $file_path;
    $contents = ob_get_clean();

    return $contents;
}

No necessarily the cleanest solution, but it seemed like it would be a surer bet since include(), given a valid file path, should always work, right?

Can you see any issue with this solution? Any new info on file_get_contents() that would make me want to switch over? Other thoughts?

Thanks!

JDGrimes commented 9 years ago

@MickeyKay, the only errors I see folks getting is because they are using file_get_contents() to open a URL. I believe only that part of the function is disabled with url_fopen. It would still work to get local files. WordPress actually uses file_get_contents() in several places.

Not necessarily the cleanest solution, but it seemed like it would be a surer bet since include(), given a valid file path, should always work, right?

Yes, include is a language construct, not a function, so it can't be disabled. The only time it would fail is if you're trying to include a URL and url_include is disabled.

I don't really see any reason that one is better than the other, though I'd still say file_get_contents() is cleaner than using output buffering.

MickeyKay commented 9 years ago

Great explanation, thanks!

On Saturday, August 2, 2014, J.D. Grimes notifications@github.com wrote:

@MickeyKay https://github.com/MickeyKay, the only errors I see folks getting is because they are using file_get_contents() to open a URL. I believe only that part of the function is disabled with url_fopen. It would still work to get local files. WordPress actually uses file_get_contents() in several places.

Not necessarily the cleanest solution, but it seemed like it would be a surer bet since include(), given a valid file path, should always work, right?

Yes, include is a language construct, not a function, so it can't be disabled. The only time it would fail is if you're trying to include a URL and url_include is disabled.

I don't really see any reason that one is better than the other, though I'd still say file_get_contents() is cleaner than using output buffering.

Reply to this email directly or view it on GitHub https://github.com/markjaquith/feedback/issues/33#issuecomment-50976455.

markjaquith commented 9 years ago

Agree with file_get_contents(). That’s generally what I'll use. Haven't heard of hosts forbidding this for local files. That would be pretty awful.