CSV Document Resource not recognised by PHP file_exists

Hey folks …

I have a Resource set up as follows:

With the CSV content type as follows:

This resource is used to output a list of MODX users to a CSV file at:


and works perfectly.

Further to this I’d like to be able to make a copy of this file to the local [hosting] filesystem on request via a snippet.

The problem is that PHP doesn’t seem to recognise https://mydomain.com/users.csv as an actual file.

file_exists( 'https://mydomain.com/users.csv' )

returns false.

Is this just a limitation of serving files in this way? Or is there some other way I can configure the resource to be recognised?

As always - I’m very grateful for any thoughts.


file_exists checks whether a file (or directory) exists in the file system. https://mydomain.com/users.csv is dynamically created when you make a https request.

What exactly are you trying to do that requires the need to call file_exists?

Hi Harry,

Thanks for your help.

I really just want to make a copy of the file to the local directory.

Here’s part of the snippet I’m creating:

$remotefile = 'https://mydomain.com/users.csv';
$localfile = $_SERVER['DOCUMENT_ROOT'] . '/assets/csv/users.csv';

if ( copy($remotefile, $localfile) ) {
	die("CSV copied");
	die("CSV copy failed.");

This always fails with “CSV copy failed”.

I later tried with file_exists but I’m clearly off on the wrong track there.

The copy works fine if I reference a URL to a csv file that actually exists.


$remotefile = 'https://mydomain.com/users.csv';
$localfile = $_SERVER['DOCUMENT_ROOT'] . '/assets/csv/users.csv';

$contents = file_get_contents($remotefile);

if ($contents && file_put_contents($localfile, $contents) {
	die("CSV copied");

die("CSV copy failed.");

As long as the https stream wrapper is enabled on the server, file_get_contents will send an actual HTTPS request in the shortest code possible. If that’s not enabled you’ll have to use curl or a HTTP client (like Guzzle) to send the request.

An alternative option could be to render the CSV resource in memory, but sending a request is simpler and makes sure it’s identical to what is normally served.

Hey @markh - thanks for checking in.

I’ve switched to your version of the code and I believe the HTTPS stream wrapper is enabled:



array(12) { [0]=> string(5) "https" [1]=> string(4) "ftps" [2]=> string(13) "compress.zlib" [3]=> string(14) "compress.bzip2" [4]=> string(3) "php" [5]=> string(4) "file" [6]=> string(4) "glob" [7]=> string(4) "data" [8]=> string(4) "http" [9]=> string(3) "ftp" [10]=> string(4) "phar" [11]=> string(3) "zip" }

I still see the same behaviour though.

On a static CSV file it works fine. But not on the dynamically generated file.

I should say that there are probably other ways I can achieve what I need to do - if there doesn’t seem to be an easy fix for this.

Have you checked the permissions on the dynamically created file? Are you sure the file handle is closed before the copy attempt?

Hi @bobray

Thanks for taking a look.

I’ve actually worked around this issue by forcing the creation of a secondary CSV file via the snippet itself. So all is good.

However, I wanted to test this and you were spot on. The CSV resource was in an admin-only resource group - taking it out of this group allowed my original code and @markh code to do what they should.

I should note that the PHP file-exists function still returns false - but as @halftrainedharry said, I don’t think that’s wholly relevant.

It’s good to know that this can be made to work.

Thanks again all for helping.


I’m glad you got it sorted – glad I could help.

1 Like

This topic was automatically closed 2 days after discussion ended and a solution was marked. New replies are no longer allowed. You can open a new topic by clicking the link icon below the original post or solution and selecting “+ New Topic”.