Download and save a file using php (keeping original filename) - php

I'm trying to download and save files like this (http://www.example.com/bajar.php?id=420633&u=7) but keeping the original filename.
I've already searched and found this code:
file_put_contents('test.rar', file_get_contents('http://www.example.com/bajar.php?id=420633&u=7');
But in this case I have to put the filename 'test.rar' manually, how can I do the same obtaining the original filename?
Many thanks!

Here's an adaptation of the thread I linked to that should work for your case. The regex is looking for the last '/' and then returning everything after it.
<?php
function get_real($url) {
$headers = get_headers($url);
foreach($headers as $header) {
if (strpos(strtolower($header),'location:') !== false) {
return preg_replace('~.*/(.*)~', '$1', $header);
}
}
}
echo get_real('http://www.example.com/bajar.php?id=420633&u=7');
?>

Related

PHP save the file using the link found by the block ID on the page

On the page https://data.mos.ru/opendata/61241/ the first url with parameter "export/get?id=" contains the last actual link to download the open data csv file //op.mos.ru/EHDWSREST/catalog/export/get?id=989116 .
The problem is that the digital ending of the url after each update is different and is not known in advance.
I have a script that works and allows me to save a file at a pre-known file url (but it only saves the old version of the file, not the current one):
<?php
function downloadJs($file_url, $save_to)
{
$content = file_get_contents($file_url);
file_put_contents($save_to, $content);
}
downloadJs('https://op.mos.ru/EHDWSREST/catalog/export/get?id=989116', realpath("./img/feeds") . '/61241.zip');
$zip = new ZipArchive;$zip->open('./img/feeds/61241.zip');$zip->extractTo('./img/feeds/61241');$zip->close();
$directory = './img/feeds/61241/'; if ($handle = opendir($directory)) { while (false !== ($fileName = readdir($handle))) { $dd = explode($fileName); $newfile = '61241.csv'; rename($directory . $fileName, $directory.$newfile); } closedir($handle); }
echo "Ok!";
?>
I need to change this PHP script so that on the page https://data.mos.ru/opendata/61241/ first determined the first link to the download file by the parameter "export/get?id=", where the link is located.
I'm not sure if you understand what you mean.
we have:
<a target="_blank" href="//op.mos.ru/EHDWSREST/catalog/export/get?id=989116" onclick="yaCounter29850344.reachGoal('download_csv')...
Perhaps we will use a little regex to get that id.
Let's say you already have its html with file_get_contents:
preg_match('#get\?id=(\d+)".* onclick="[^"]+csv[^"]+"#', $html, $matches);
echo $matches[1]; // 989116

Perform Delete, Edit and search operation on a file using php

I have a task to do in which i have to list the directories with it's files which i did, but i don't understand how to delete file or edit specific file in the directories any help will be appreciated Thanks.
<?php
error_reporting(0);
if(isset($_GET['dir']))
{
// /$path = 'E:\xampp\\'.$_GET['dir'];
$path = $_GET['dir'];
}
else
{
$path = 'E:\xampp\\';
}
if(is_dir($path))
{
$arrDir = scandir($path);
echo "<ul>";
foreach ($arrDir as $key => $value)
{
echo "<a href='http://localhost/vishrut/FileUpload/filelist.php?
dir=".$path.'/'.$value."'>".$value.'</a><br>';
}
echo "</ul>";
}
else
{
echo "<textarea>";
echo file_get_contents($path);
echo "</textarea>"."<br>";
}
?>
There are lots of PHP's functions to handle files: https://www.php.net/manual/en/ref.filesystem.php
For your needs see these:
file_get_contents to read the entire file contents
file_put_contents to write the content in a file
unlink to delete a file
So, the steps to modify a file may be:
get the complete contents with file_get_contents:
$contents = file_get_contents($filePath);
apply your edits to the $contents content:
$newContents = ...
overwrite the file content:
file_put_contents($filePath, $newContents);
To delete a file is simple:
unlink($filePath);
It's important to note that your code is subjected to injection because you don't check the user data passed with $_GET.
If your script will be used only by you it's ok, instead you must check all user input: the first rule of Web programming is NEVER TRUST YOUR USERS! Also trusted users may write wrong characters in the url and that may have unexpected results (e.g. delete the wrong file!)
Read https://www.php.net/manual/en/mongodb.security.script_injection.php

open file on client stored on server

I want to open a server stored html report file on a client machine.
I want to bring back a list of all the saved reports in that folder (scandir).
This way the user can click on any of the crated reports to open them.
So id you click on a report to open it, you will need the location where the report can be opend from
This is my dilemma. Im not sure how to get a decent ip, port and folder location that the client can understand
Here bellow is what Ive been experimenting with.
Using this wont work obviously:
$path = $_SERVER['DOCUMENT_ROOT']."/reports/saved_reports/";
So I though I might try this instead.
$host= gethostname();
$ip = gethostbyname($host);
$ip = $ip.':'.$_SERVER['SERVER_PORT'];
$path = $ip."/reports/saved_reports/";
$files = scandir($path);
after the above code I loop through each file and generate a array with the name, date created and path. This is sent back to generate a list of reports in a table that the user can interact with. ( open, delete, edit)
But this fails aswell.
So im officially clueless on how to approach this.
PS. Im adding react.js as a tag, because that is my front-end and might be useful to know.
Your question may be partially answered here: https://stackoverflow.com/a/11970479/2781096
Get the file names from the specified path and hit curl or get_text() function again to save the files.
function get_text($filename) {
$fp_load = fopen("$filename", "rb");
if ( $fp_load ) {
while ( !feof($fp_load) ) {
$content .= fgets($fp_load, 8192);
}
fclose($fp_load);
return $content;
}
}
$matches = array();
// This will give you names of all the files available on the specified path.
preg_match_all("/(a href\=\")([^\?\"]*)(\")/i", get_text($ip."/reports/saved_reports/"), $matches);
foreach($matches[2] as $match) {
echo $match . '<br>';
// Again hit a cURL to download each of the reports.
}
Get list of reports:
<?php
$path = $_SERVER['DOCUMENT_ROOT']."/reports/saved_reports/";
$files = scandir($path);
foreach($files as $file){
if($file !== '.' && $file != '..'){
echo "<a href='show-report.php?name=".$file. "'>$file</a><br/>";
}
}
?>
and write second php file for showing html reports, which receives file name as GET param and echoes content of given html report.
show-report.php
<?php
$path = $_SERVER['DOCUMENT_ROOT']."/reports/saved_reports/";
if(isset($_GET['name'])){
$name = $_GET['name'];
echo file_get_contents($path.$name);
}

Using fopen, fwrite multiple times in a foreach loop

I want to save files from an external server into a folder on my server using fopen, fwrite.
First the page from the external site is loaded, and scanned for any image links. Then that list is sent from an to the fwrite function. The files are created, but they aren't the valid jpg files, viewing them in the browser it seems like their path on my server is written to them.
Here is the code:
//read the file
$data = file_get_contents("http://foo.html");
//scan content for jpg links
preg_match_all('/src=("[^"]*.jpg)/i', $data, $result);
//save img function
function save_image($inPath,$outPath)
{
$in= fopen($inPath, "rb");
$out= fopen($outPath, "wb");
while ($chunk = fread($in,8192))
{
fwrite($out, $chunk, 8192);
}
fclose($in);
fclose($out);
}
//output each img link from array
foreach ($result[1] as $imgurl) {
echo "$imgurl<br />\n";
$imgn = (basename ($imgurl));
echo "$imgn<br />\n";
save_image($imgurl, $imgn);
}
The save_image function works if I write out a list:
save_image('http://foo.html', foo1.jpg);
save_image('http://foo.html', foo1.jpg);
I was hoping that I'd be able to just loop the list from the matches in the array.
Thanks for looking.
There are two problems with your script. Firstly the quote mark is being included in the external image URL. To fix this your regex should be:
/src="([^"]*.jpg)/i
Secondly, the image URLs are probably not absolute (don't include http:// and the file path). Put this at the start of your foreach to fix that:
$url = 'http://foo.html';
# If the image is absolute.
if(substr($imgurl, 0, 7) == 'http://' || substr($imgurl, 0, 8) == 'https://')
{
$url = '';
}
# If the image URL starts with /, it goes from the website's root.
elseif(substr($imgurl, 0, 1) == '/')
{
# Repeat until only http:// and the domain remain.
while(substr_count($url, '/') != 2)
{
$url = dirname($url);
}
}
# If only http:// and a domain without a trailing slash.
elseif(substr_count($imgurl, '/') == 2)
{
$url .= '/';
}
# If the web page has an extension, find the directory name.
elseif(strrpos($url, '.') > strrpos($url, '/'))
{
$url = dirname($url);
}
$imgurl = $url. $imgurl;
fopen isn't guaranteed to work. You should be checking the return values of anything they may return something different on error...
fopen() - Returns a file pointer resource on success, or FALSE on error.
In fact all the file functions return false on error.
To figure out where it is failing I would recommend using a debugger, or printing out some information in the save_image function. i.e. What the $inPath and $outPath are, so you can validate they are being passed what you would expect.
The main issue I see is that the regex may not capture the full http:// path. Most sites leave this off and use relative paths. You should code in a check for that and add it in if that is not present.
Your match includes the src bit, so try this instead:
preg_match_all('/(?<=src=")[^"]*.jpg/i', $data, $result);
And then I think this should work:
unset($result[0]);
//output each img link from array
foreach ($result as $imgurl) {
echo "$imgurl<br />\n";
$imgn = (basename ($imgurl));
echo "$imgn<br />\n";
save_image($imgurl, $imgn);
}

preg_match for <?php, <?, and/or ?>

I'm not very familiar with regEx's and I'm trying to find a preg_match regex for searching for any of the following strings within a file and if found it will halt it. I already have the fopen and fgets and fclose setup I just need to use a regex inside of a preg_match for the following php tags:
<?php
<?
?>
so if preg_match returns 1 than this will skip this file and not upload it. I am using the $_FILES array to upload it via post, so I'm hoping I can use the $_FILES['file']['tmp_name'] variable for this to read through the file.
Thanks for your help with this :)
EDIT
if (in_array('application/x-httpd-php', $files[$filid]['mimetypes']) && ($_FILES[$value]['type'][$n] == 'application/octet-stream' || $_FILES[$value]['type'][$n] == 'application/octetstream'))
{
$file_extension = strtolower(substr(strrchr($_FILES[$value]['name'][$n], '.'), 1));
if ($file_extension == 'php')
{
// Reading the current php file to make sure it's a PHP File.
$fo = fopen($_FILES[$value]['tmp_name'][$n], 'rb');
while (!feof($fo))
{
$fo_output = fgets($fo, 16384);
// look for a match
if (preg_match([REG EX HERE], $fo_output) == 1)
{
$php = true;
break;
}
}
fclose($fo);
}
}
OK, I apologize, but actually, what I am doing is I need to find a PREG MATCH. Because if it is a PHP FILE, I need to set the MIME TYPE to: application/x-httpd-php within the database. BECAUSE I'm also allowing PHP Files to be uploaded as well in certain instances. So hopefully the code I posted above makes more sense to you all now.
Can someone please help me with a preg_match regex for this please?
/(?:<\?(?!xml)|\?>)/
(15 chars)
If you want to parse the file, try the following instead:
function containsPhp($file) {
if(!$content = file_get_contents($file)) {
trigger_error('Not a file');
return false;
}
foreach(token_get_all($content) as $token) {
if(is_array($token) && in_array(current($token), array(T_OPEN_TAG, T_OPEN_TAG_WITH_ECHO))) {
return true;
}
}
return false;
}
... besides checking for a php extension (php, php5, phtml, inc etc).
\?>|<\?((?=php)|(?!\w))

Categories