PHP - copy() fails on URL with curly braces/brackets - php

I'm having an issue with the copy() function in PHP.
I need to copy a remote URL that looks like: https://example.co.uk/{8d988e90-a325-4a1c-a340-a489166286b8}/{14409287-2c29-4b51-91e4-0891b5619659}/main/imgnew-(2).jpg, to my local drive.
Here is the part of my code that fails, along with some context for the $RemoteURL variable:
$replace = array('%7B', '%7D','%28','%29');
$entities = array('{', '}','(',')');
$RemoteURL = str_replace($entities, $replace, "https://example.co.uk/{8d988e90-a325-4a1c-a340-a489166286b8}/{14409287-2c29-4b51-91e4-0891b5619659}/main/imgnew-(2).jpg");
$PicName = "new.jpg"
if(copy($RemoteURL,"C:\Users\Me\Downloads\Pictures\" . $PicName)){
echo "<script>console.log(\"(" . $RemoteURL . ") copied to waiting.\")</script>";
} else {
echo "<p class='float red'>READ ERROR</p>";
}
However, this throws the error:
Warning: copy(https://example.co.uk/%7B8d988e90-a325-4a1c-a340-a489166286b8%7B/%7B14409287-2c29-4b51-91e4-0891b5619659%7B/main/imgnew-%282%29.jpg): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
What is it exactly I'm missing here, or what is it that PHP doesn't like about the URL itself?

Turns out the issue that was producing the error above was that I had an accented character that was problematic.
è was giving an error, which was fixed by creating a function that replaced certain parts:
function URLEncodeRules($string) {
$replacements = array('%C3%A9','%C3%A8');
$entities = array('é','è');
return str_replace($entities, $replacements, $string);
}
$RemoteURL = URLEncodeRules($CaptureRow['URL']);
if(copy($RemoteURL,"image.jpg")){
echo "Success!;
}

Try using url_encode();
Hope this will help you.
Thanks,

Related

php - one time access by looking up serial in a .dat file

i've now written this short script.
It records a serial or token number, checks to see if its in a .dat file, and allows access if its present. Otherwise it denies access to the site.
It also removes the token from the file once it has been redeemed as it were.
However, when i add multiple tokes in the dat file, the code doesn work properly. It only works with a single entry. How would i make it work for multiple entries.
im thinking of maybe implementing some sort of array somewhere? or explode?
index.php
require_once "married.php";
session_start();
$url_request = (isset($_SERVER['HTTPS']) ? "https" : "http") .
"://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$ip = $_SERVER['REMOTE_ADDR'];
$token = substr($url_request,45);
$_SESSION["cookie"] = $token;
$tk = $_SESSION["cookie"];
$ips = array();
$page = file("urls.dat");
foreach($page as $line)
{
array_push($ips, $line);
}
if(in_array($tk, $ips))
{
//header("Location: mysite.co.uk");
echo "<title>My Site</title>Here is my site";
$file = fopen("ip_match.dat","a");
fwrite($file,$tk . " " . $ip . "\r\n");
fclose($file);
$oldMessage = $_SESSION["cookie"];
$deletedFormat = "";
$str=file_get_contents('urls.dat');
$str=str_replace("$oldMessage", "$deletedFormat",$str);
file_put_contents('urls.dat', $str);
exit;
} else {
echo ("<title>404 Not Found</title>
<h1>Not Found</h1>The requested URL was not found on this server.
<br>
<br>
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request. test");
exit;
}
urls.dat
1089yht
url: http://mmmmmmmmmmmmm.co.uk/url/index.php?key=1089yht
ps. Happy Holidays all!
Look at JSON. You could do something like this:
$tokens = ['foo', 'bar'];
file_put_contents('urls.json', json_encode($tokens));
// and then you can decode it back
// returns ['foo', 'bar']
$decodedTokens = json_decode(file_get_contents('urls.json'));
If you still want to use simple text file, you could save every record at new line and then load line by line.
$tokens = [];
while(! feof($file)) {
$line = fgets($file);
// or save to array
$tokens[] = $line;
}
fclose($file);
try
$str = preg_replace("/{$oldMessage}/", $deletedFormat, $str, 1);
Instead of
$str=str_replace("$oldMessage", "$deletedFormat",$str);
Because: str_replace replaces everything.
preg_replace lets you limit how many replacements.

New line character not working in php

I am creating a log file for all api call in my application which is written in php (Symfony).
While creating log file I have used "\n" as new line characters but it's not working.
my code is -
$log = "\n Account: ".$Account."---ID: ".$ID;
$log .= "\n Params: ".$params."\n";
$log .= "\n response: ".$response."\n";
It gives me out put in one line, I also tried "\r\n" and "PHP_EOL" but it doesn't works.
How can I able to fix this issue?
Thanks
I think you should replace \n with <br>, but without space in the brackets
Below should work. And I am using this on my all projects to find the error
$contents = file_get_contents('text.txt'); // TO LOAD THE EXISTING CONTENTS OF ERROR LOG FILE
$contents .= PHP_EOL."\n Account: ".$Account."---ID: ".$ID; // CONCAT. ACCOUNT NUMBER
$contents .= PHP_EOL."\n Params: ".$params."\n"; // CONCAT. PARAMS
$contents .= PHP_EOL."\n response: ".$response."\n"; // CONCAT. RESPONSE
file_put_contents('text.txt', $contents, FILE_APPEND); // WRITING ENIRE LOG BACK INTO LOG FILE

Storing pdf to varbinary(max) field with php and MS SQL

I'm working with MS SQL 2005 and PHP, and I got this code
move_uploaded_file($_FILES["file"]["tmp_name"],"temp/" . $_FILES["file"]["name"]);
$data = fopen("temp/"$_FILES["file"]["name"], "rb");
$content =fread($data,$_FILES['file']['size']);
$content=addslashes($content);
$sql = "INSERT INTO docs(file) value($content)";
if(!mssql_query($sql)){
die('MSSQL error: ' . mssql_get_last_message());
}
and I got this error: MSSQL error: Incorrect syntax near 'PDF'
PD: excuse my poor english
I found the solution: the code would look like:
function mssql_escape($data) {
if(is_numeric($data))
return $data;
$unpacked = unpack('H*hex', $data);
return '0x' . $unpacked['hex'];
}
-
move_uploaded_file($_FILES["file"]["tmp_name"],"temp/" . $_FILES["file"]["name"]);
$data = fopen("temp/"$_FILES["file"]["name"], "rb");
$content =fread($data,$_FILES['file']['size']);
$content=mssql_escape($content);//Call mssql_escape function
$sql = "INSERT INTO docs(file) value($content)";
if(!mssql_query($sql)){
die('MSSQL error: ' . mssql_get_last_message());
}
Use parameters. See the documentation - specifically the first example for mssql_bind - for instructions on how to do that.
You're trying to insert the contents of the PDF file as a string, and you have no quotes around that string. But even if you wrap $contents in quotes, it probably still will not work. There may be binary in the file contents that simply cannot be inserted in this way.
Also, it may be easier to just save the PDF file somewhere in your filesystem and save the path to the file in your database. That way you won't have huge (megabytes!) records in your database and the files will probably be quicker to access.
I found the solution: the code would look like:
function mssql_escape($data) {
if(is_numeric($data))
return $data;
$unpacked = unpack('H*hex', $data);
return '0x' . $unpacked['hex'];
}
-
move_uploaded_file($_FILES["file"]["tmp_name"],"temp/" . $_FILES["file"]["name"]);
$data = fopen("temp/"$_FILES["file"]["name"], "rb");
$content =fread($data,$_FILES['file']['size']);
$content=mssql_escape($content);//Call mssql_escape function
$sql = "INSERT INTO docs(file) value($content)";
if(!mssql_query($sql)){
die('MSSQL error: ' . mssql_get_last_message());
}

php - file_get_contents - Downloading files with spaces in the filename not working

I am trying to download files using file_get_contents() function.
However if the location of the file is http://www.example.com/some name.jpg, the function fails to download this.
But if the URL is given as http://www.example.com/some%20name.jpg, the same gets downloaded.
I tried rawurlencode() but this coverts all the characters in the URL and the download fails again.
Can someone please suggest a solution for this?
I think this will work for you:
function file_url($url){
$parts = parse_url($url);
$path_parts = array_map('rawurldecode', explode('/', $parts['path']));
return
$parts['scheme'] . '://' .
$parts['host'] .
implode('/', array_map('rawurlencode', $path_parts))
;
}
echo file_url("http://example.com/foo/bar bof/some file.jpg") . "\n";
echo file_url("http://example.com/foo/bar+bof/some+file.jpg") . "\n";
echo file_url("http://example.com/foo/bar%20bof/some%20file.jpg") . "\n";
Output
http://example.com/foo/bar%20bof/some%20file.jpg
http://example.com/foo/bar%2Bbof/some%2Bfile.jpg
http://example.com/foo/bar%20bof/some%20file.jpg
Note:
I'd probably use urldecode and urlencode for this as the output would be identical for each url. rawurlencode will preserve the + even when %20 is probably suitable for whatever url you're using.
As you have probably already figured out urlencode() should only be used on each portion of a URL that requires escaping.
From the docs for urlencode() just apply it to the image file name giving you the problem and leave the rest of the URL alone. From your example you can safely encode everything following the last "/" character
Here is maybe a better solution. If for any reason you are using a relative url like:
//www.example.com/path
Prior to php 5.4.7 this would not create the [scheme] array element which would throw off maček function. This method may be faster as well.
$url = '//www.example.com/path';
preg_match('/(https?:\/\/|\/\/)([^\/]+)(.*)/ism', $url, $result);
$url = $result[1].$result[2].urlencode(urldecode($result[3]));
Assuming only the file name has the problem, this is a better approach. only urlencode the last section ie. file name.
private function update_url($url)
{
$parts = explode('/', $url);
$new_file = urlencode(end($parts));
$parts[key($parts)] = $new_file;
return implode("/", $parts);
}
This should work
$file = 'some file name';
urlencode($file);
file_get_contents($file);

Script to download and extract zip files returns errors

Hey everyone, I have written a script that downloads a zip file from a remote source, and then is supposed to extract the zip file to a directory. Below is the script:
<?php
$url = "http://example.com/some_file.zip";
download($url,'file.zip');
function download($url,$file_name = NULL){
if($file_name == NULL){ $file_name = basename($url);}
$url_stuff = parse_url($url);
$port = isset($url_stuff['port']) ? $url_stuff['port'] : 80;
$fp = fsockopen($url_stuff['host'], $port);
if(!$fp){ return false;}
$query = 'GET ' . $url_stuff['path'] . " HTTP/1.0\n";
$query .= 'Host: ' . $url_stuff['host'];
$query .= "\n\n";
fwrite($fp, $query);
while ($tmp = fread($fp, 8192)) {
$buffer .= $tmp;
}
preg_match('/Content-Length: ([0-9]+)/', $buffer, $parts);
$file_binary = substr($buffer, - $parts[1]);
if($file_name == NULL){
$temp = explode(".",$url);
$file_name = $temp[count($temp)-1];
}
if(!file_exists("packages")){ mkdir("packages", 0755);}
$file_open = fopen("packages/" . $file_name,'w');
if(!$file_open){ return false;}
fwrite($file_open,$file_binary);
$zip = zip_open(realpath("packages")."/".$file_name);
if ($zip) {
while ($zip_entry = zip_read($zip)) {
$fp = fopen("some_dir/".zip_entry_name($zip_entry), "w");
if(zip_entry_open($zip, $zip_entry, "r")) {
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
fwrite($fp,"$buf");
zip_entry_close($zip_entry);
fclose($fp);
}
}
zip_close($zip);
}
fclose($file_open);
return true;
}
?>
The issue that I have is that while the downloading of the remote file works flawlessly, I can't seem to extract it. The zip_read() and zip_close() return errors saying that it "expects parameter 1 to be resource, integer given...", which I have found means that the zip_open() was unable to extract and is returning an error code, which I have found to be "19" meaning "Zip File Function error: Not a zip archive". However, I know the file I am downloading is, in fact, a zip file. Can anyone explain this odd behavior and provide a fix? It would be much appreciated!
Quoting php.net: "zip_open() ... Returns a resource handle for later use with zip_read() and zip_close() or returns the number of error if filename does not exist or in case of other error."
This means you cannot test if ($zip) like that. Try
if ( is_resource($zip) ) {
// stuff
} else {
print "Zip_open() returned error $zip\n";
}
edit: Apart from that, you need to cut the response in 2 parts properly. You are relying heavily on the Content-Length parameter. You don't check if the preg_match actually matched. A lot of things can go wrong and you should check those things. Try splitting the content on the first empty line (explode on \r\n\r\n or something like that)
Besides the fread() loop should check for feof(), since you would stop reading now if for some reason you would encounter an empty read. Copy&paste from php.net:
while (!feof($handle)) {
$contents .= fread($handle, 8192);
}
But we can go on and on here. Three main points have to be made:
read the fantastic manual (php.net)
check return values
don't assume you know things you don't
those are related: you must lookup the manual to see what return values you might encounter.

Categories