Thanks for that suggestion - looks good. I'd totally forgotten about curl functions. I'll have to brush up my skills a bit! . However, I'll certainly give it a try.
Automatically send a text file created on server to local machine?
maxxd
Hi. Sorry to be a nuisance but I'm definitely very rusty these days (been retired - officially - 20 years).
Looking at the code you suggested for the local machine part, does $addr refer to the file containing the function you suggested for the server end - for example for local testing:
$addr = http://localhost/curl-server.php?
I hate to think how many years ago since I last tried CURL!
- Edited
sagecelt Looking at the code you suggested for the local machine part, does $addr refer to the file containing the function you suggested for the server end
Yes. For instance, if you uploaded the server script to https://myawesomesite.com/script
, $addr would be https://myawesomesite.com/script?key=123
.
The other option is to simply run it in the browser. Put in some output directives and actually go to the address. That way you wouldn't have to deal with cURL and you could just do it whenever you need/want to.
maxxd
I thought I had it with this on the local PC:-
`<?php
// Initialize the cURL session
$addr = 'http://localhost/curl-server.php?key=123'; // for example
$ch = curl_init();
// Ask cURL to return the contents in a variable instead of simply echoing them to the browser.
curl_setopt($ch, CURLOPT_URL, $addr);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Execute the cURL session
$output = curl_exec($ch);
// Check if any error occurred ==============================
if(curl_errno($ch))
{
echo 'Curl error: ' . curl_error($ch);
}
// Close handle
curl_close($ch);
// End error check code =====================================
echo 'Should now be executing curl-server!!';
// doSomethingWithData($output);
?>That runs and shows the comment on the screen. The next comment is the first line in the server script:
echo 'Reached server code ok';`
but that never gets executed. I must be doing something wrong but I can't see what?
Oops - code and ordinary text got screwed up - hope it's understandable?
If you are concerned about someone else obtaining sensitive data, it's probably not wise to have it accessible via HTTP. HTTPS does give you some little security because traffic between your "local machine" and the remote server is encrypted in transit and can't easily be snooped by any third party. However, if anyone were to obtain that url, they could also download the text file. Maxxd has a good suggestion to avoid writing the text file if you can. If this step is absolutely necessary, then save it outside of the web root so it cannot be downloaded directly by some random visitor. If your server shows directory indexes, this could be very problematic.
Running an SFTP server on your local machine can be a chore to set up and would require you to keep your local machine on whenever this transfer is supposed to happen. If you typically connect to the internet through a router like I do, you'd have to learn how to do port forwarding of SFTP connections to the router to the correct machine on your LAN. NogDog is right that pulling is better.
Maxxd has a reasonable suggestion about using a key, but that key is far too simple. If you take that approach, generate a much longer one. Maybe try this code:
$token = bin2hex(openssl_random_pseudo_bytes(16));
# or in php7
$token = bin2hex(random_bytes(16));
Another option is to encrypt the file with something like gnupg on the server and email it. BCEncrypt is pretty old now, but might work. It takes some figuring out, but uses serious cryptographic tools to encrypt data so you can email it without worrying too much.
As for your curl script, you apparently haven't included the entire script -- the output you describe doesn't correspond to anything in your PHP code.
@sagecelt - If I'm reading correctly, you're concerned about not seeing the line 'Reached server code ok' echo to the screen after the line 'Should now be executing curl-server!!'? By the time you get to outputting the line 'Should now be executing curl-server!!', the server script has already been executed. The output of that server script should now be stored in $output thanks to the return transfer directive. So, if you run it again but output $output in your local script, you should see 'Reached server code ok'.
That having been said, @sneakyimp makes some very good points and yes, if you do go with a key make it much, much longer and more secure than '123'. Best would be to create and use a true nonce, but that would entail using more than one page or step in getting the data out of the database and to your local computer.
maxxd
Hi maxxd. You and sneakyimp are incredibly helpful and generous in your professional advice in relation to the question I posed. Thank you both very much indeed: I can’t tell you how much I appreciate it.
I am, of course, trying out ideas on my own LAN using Wampserver as the host. In practice I would, of course, use HTTPS and do something about passwords.
I must be even rustier than I thought. I seem to be almost there but I’m not getting anything in what I expected to be the return value. Here’s my test code.
Local script:-
<?php
$addr = “http://localhost/curl-server.php?key=123”;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $addr);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$return = curl_exec($ch);
if(curl_errno($ch)) {
echo “Curl error: “ . curl_error($ch); }
curl_close($ch);
echo “Script completed <br>”;
echo “Output = “ . “ “ . $return;
?>
I expected to get a string returned in the variable $return. However, it seems to be empty. This is the server script:-
<?php
require_once 'forms/incl/config.php';
$dsn = 'mysql:host='. $host . ';dbname='. $dbname;
if(!$pdo = new PDO($dsn, $user, $password)) {
die('PDO setup failed <br>'); }
if(!$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC)) {
die('setAttribute failed <br>'); }
function selectSomeData(){
if(empty($_GET['key']) || $_GET['key'] !== '123'){
die('You are not authorised!');
}
$qry = 'We have completed the script.';
}
selectSomeData();
?>
I’m missing something obvious I’m sure but I’m d….d if I can spot it! Sorry for being so dumb over this.
- Edited
Couple things in the scripts you just posted. First - and I have to assume this has to do with copy/paste into the post editor here - all your double quotes are fancy quotes, and that's throwing an error. I don't know what IDE you're using, but if it's formatting text that's going to be an issue - try VSCode or even Notepad++.
Second, you don't ever actually echo out $qry
in your second script, so nothing gets returned to $return
in your first.
Lastly, I don't know what 'forms/incl/config.php' looks like, but I assume if it wasn't working you'd see your error message in $return
, so it should be good.
I ran your scripts (without the include) here, and once $qry
was echoed in the second script, everything worked as expected. Turn on error reporting and see if there's anything else throwing a notice or an error.
- Edited
maxxd
Thanks. I'm already using VSCode and I only changed the single quotes to double because I thought the single quotes may have messed up my earlier post formatting the code. The use of single quotes in a post to signify code is new to me. All the forums I've ever used in the past used the simple tags "code" and "/code" but included in square brackets; which, after my initial post before editing shows me that it works here too!
'forms/incl/config.php' simply contains the actual host, database name, username and password variables.
I cut the scripts down just for testing and I could, actually, have left out the whole db enquiry for this exercise.
The scripts ran cleanly here and echoed the two text lines at the bottom of the local script so it ran all the way through without throwing an error. I expected $return to contain the string.
I can't quite see how to echo out $qry
in my second script: having two scripts interlinking is throwing my thinking awry.
The double quotes I'm referring to are in the first script - echo “Output = “ . “ “ . $return;
instead of echo "Output = "." ".$return;
for instance. You can see that the quote marks from your post are curvy, or fancy. Check to make sure they're not that way in VSCode.
As for outputting $qry, just literally echo it. Like so: echo $qry;
PS: use backticks to signify code in this forum - it recognizes markdown formatting.
A little more explanation - the two scripts aren't interlinking at all. The script on the server is just creating an output stream, which the local script is consuming via cURL's RETURNTRANSFER directive. Think of it like this: the server script implicitly calls php://stdout
and pipes anything from an echo statement into that stream. The local script implicitly calls php://stdin
, creating a destination for the server script's php://stdout
contents. So, it's a lot like AJAX in that the scripts aren't actually communicating with each other, they're just putting data out there and assuming that the handler script can actually handle that data.
maxxd
Sorry, yes I did write the lines with curly quotes in Word and cut & paste it in the forum. In VSCode all is well.
I'm afraid I don't know what you mean by a backtick; I'm using a UK keyboard and the word backtick doesn't appear in UK English. What seemed to work ok was to use the single inverted commas to enclose the code items.
So, if the local script is the destination for the server script's php//stdout
should I read that data with a line in the local script like $contents = file_get_contents("php://stdin");
and then echo $contents;
?
Try this for your server script -
function selectSomeData(){
if(empty($_GET['key']) || $_GET['key'] !== '123'){
die('You are not authorised!');
}
echo 'We have completed the script.';
}
selectSomeData();
The backtick has nothing to do with your question, but just because...
Not sure whey you are fiddling with stdin/stdout. If I were you, I'd start by having your curl script request a page that does something super simple like this:
echo "THIS IS WORKING";
Once you are sure your curl script is properly fetching that page into your $return
variable, then you can worry about working up a more complicated script to selectSomeData().
As for the second script, which fetches the data, maxxd is right. The function you've posted doesn't actually output anything to be read on the other end.
I think I muddied the waters talking about stdin and stdout - they're not actually being used here at all. Just cURL to the script on the server, output something from the script on the server, and print it from the local script's $return variable.
Sorry if I got everyone confused.
- Edited
Thanks to everybody who has contributed here. I think I've finally got my ancient brain in gear and the very simple test - where there's no DB query - works fine. The simple statement gets returned as expected. Now to try and get a DB query executed and the results returned.
There may appear to be a long delay in my response at times but that is probably because we're in different time zones (UK/USA?).
Added comment:-
OK, it's now a bit later. I've changed the script, selected a record from the DB and it's worked perfectly! Can't thank you all enough .
PS: Is it possible to pass a parameter from the local script into the server script for DB select conditions?
sagecelt Is it possible to pass a parameter from the local script into the server script for DB select conditions?
Append it to the URL - https://myawesomesite.com/script?key=123&another_param=stuff
Then grab it from $_GET in your script as normal. Just remember to use prepared statements if it's going to be used in the query itself.
I will repeat that you should be wary of an unwanted visitor stumbling across this url and digging through your sensitive data. Having a secret key is a good step in the right direction, but you should also make sure you connect to the server using HTTPS (i.e., SSL or TSL to encrypt your requests) or any manner of other people may be able to see your url and key. It might be a good idea to monitor your access logs for this url and make sure you are the only one who ever connects to it.
If it's just you accessing the url, you don't need to worry so much about bad guys attempting SQL injection. But you'll probably want to validate any $GET values coming in to make sure they are safe. Using PDO can help you reduce the risk if you aren't just sticking user input from $GET directly into an SQL string to run as a query.