I'm wanting to generate a dynamic zip/gzip file using php (user clicks button/link/whatever, and sends file to download) which contains a folder structure that may or may not have files (could be blank or contain data) in all the folders.
The aim is to be able to unzip this file and have a folder/file structure ready to go.
I believe I am familiar with everything involved, except how to generate the file without creating the files on my server locally, then zipping them and sending for download. This seems to include 'writing the files to the server' as a sort of middle man that I would just assume bypass if possible.
I would like to assume this is as easy as sending raw data to the browser with a zip/gzip header, but I haven't had much luck finding any information on this.
Any pointers in the right direction would be most helpful.
You can do that with the ZipArchive class. Have a look at function such as ZipArchive::addFromString() which will allow you to add files to the archive without actually saving it them to disk first.
Related
I wish to download a lot of jpegs keeping the original name and their paths.
Example: http://www.somesite.org/path1/image1.jpg, should be downloaded on www.mysite.com/path1/image1.jpg (and creating the "path1" directory if it does not exist) This is repeated a lot of times, fetching the original download site from a field on a database.
Is it possible? Keep in mind that I can't use cURL nor wget since I am on a "limited" hosting service.
Well, first of all you have to find a method to get all download links. There are several ways to fetch data from a database, depending on what database it is (mysql, exel, textfile...)
Then you need to use ftp to upload these files into your database. Strip down the original link to the path (remove the www.somesite.org) and use your site + the path for storing.
This is very manageable, but we are not here to do all the thinking for you. Use google and try methods first, then come back if you are facing a specific problem.
I have a simple site which allows users to upload files (among other things obviously). I am teaching myself php/html as I go along.
Currently the site has the following traits:
--When users register a folder is created in their name.
--All files the user uploads are placed in that folder (with a time stamp added to the name to avoid any issues with duplicates).
--When a file is uploaded information about it is stored in an SQL database.
simple stuff.
So, now my question is what steps do I need to take to:
Prevent google from archiving the uploaded files.
Prevent users from accessing the uploaded files unless they are logged in.
Prevent users from uploading malicious files.
Notes:
I would assume that B, would automatically achieve A. I can restrict users to only uploading files with .doc and .docx extensions. Would this be enough to save against C? I would assume not.
There is a number of things you want to do, and your question is quite broad.
For the Google indexing, you can work with the /robots.txt. You did not specify if you also want to apply ACL (Access Control List) to the files, so that might or might not be enough. Serving the files through a script might work, but you have to be very careful not to use include, require or similar things that might be tricked into executing code. You instead want to open the file, read it and serve it through File operations primitives.
Read about "path traversal". You want to avoid that, both in upload and in download (if you serve the file somehow).
The definition of "malicious files" is quite broad. Malicious for who? You could run an antivirus on the uplaod, for instance, if you are worried about your side being used to distribute malwares (you should). If you want to make sure that people can't harm the server, you have at the very least make sure they can only upload a bunch of filetypes. Checking extensions and mimetype is a beginning, but don't trust that (you can embed code in png and it's valid if it's included via include()).
Then there is the problem of XSS, if users can upload HTML contents or stuff that gets interpreted as such. Make sure to serve a content-disposition header and a non-html content type.
That's a start, but as you said there is much more.
Your biggest threat is going to be if a person manages to upload a file with a .php extension (or some other extension that results in server side scripting/processing). Any code in the file runs on your server with whatever permissions the web server has (varies by configuration).
If the end result of the uploads is just that you want to be able to serve the files as downloads (rather than let someone view them directly in the browser), you'd be well off to store the downloads in a non web-accessible directory, and serve the files via a script that forces a download and doesn't attempt to execute anything regardless of the extension (see http://php.net/header).
This also makes it much easier to facilitate only allowing downloads if a person is logged in, whereas before, you would need some .htaccess magic to achieve this.
You should not upload to webserver-serving directories if you do not want the files to be available.
I suggest you use X-Sendfile, which is a header that instructs the server to send a file to the user. Your PHP script called 'fetch so-and-so file' would do whatever authentication you have in place (I assume you have something already) and then return the header. So long as the web server can access the file, it will then serve the file.
See this question: Using X-Sendfile with Apache/PHP
I'm trying to implement an script that reads the content(files and folders) of a certain directory and writes it in a database. My goal is create an software that allows me to organize those files and folders relating description and tags to them, without affecting the correspondig physical files in the disk.
But for now I'm facing a logical problem: How do I make a direct connection between that physical file and the database register? I want that, even if the physical file, for some reason, is edited or moved to another folder inside the root directory, the software is still able to relate that file with its original register in the database.
My first idea was to use a checksum hash to identify every file but, I'm guessing that if the file is edited, so does the hash, doesn't it? Besides that, I also think that a folder itself can't be checked that way.
Another solution that came up to my mind was applying a unique key in the beginning of every file and folder name in the directory. That may work, but it seems to me like an improvised solution and, therefore, I'mhoping that there may be another way to do it that I haven't considered yet.
Does anyone have an advice on that?
Under Linux, you can track files by inode, which won't change if the file gets moved or renamed. You can even get notified when a file changes.
have you considered storing the file in the database?
You can't.
It looks that there is no way to identify the file: neither by content nor by pathname.
One workaround might be: use path as id (and use them as reference in the DB) and do not use system tools (like mv) to move files but your own script which updates the file system and the database.
I'm building a web server out of a spare computer in my house (with Ubuntu Server 11.04), with the goal of using it as a file sharing drive that can also be accessed over the internet. Obviously, I don't want just anyone being able to download some of these files, especially since some would be in the 250-750MB range (video files, archives, etc.). So I'd be implementing a user login system with PHP and MySQL.
I've done some research on here and other sites and I understand that a good method would be to store these files outside the public directory (e.g. /var/private vs. /var/www). Then, when the file is requested by a logged in user, the appropriate headers are given (likely application/octet-stream for automatic downloading), the buffer flushed, and the file is loaded via readfile.
However, while I imagine this would be a piece of cake for smaller files like documents, images, and music files, would this be feasible for the larger files I mentioned?
If there's an alternate method I missed, I'm all ears. I tried setting a folders permissions to 750 and similar, but I could still view the file through normal HTTP in my browser, as if I was considered part of the group (and when I set the permissions so I can't access the file, neither can PHP).
Crap, while I'm at it, any tips for allowing people to upload large files via PHP? Or would that have to be don via FTP?
You want the X-Sendfile header. It will instruct your web server to serve up a specific file from your file system.
Read about it here: Using X-Sendfile with Apache/PHP
That could indeed become an issue with large files.
Isn't it possible to just use FTP for this?
HTTP isn't really meant for large files but FTP is.
The soluton you mentioned is the best possible when the account system is handled via PHP and MySQL. If you want to keep it away from PHP and let the server do the job, you can protect the directory by password via .htaccess file. This way the files won't go through the PHP, but honestly there's nothing you should be worried about. I recommend you to go with your method.
I would like to write a setup script for my PHP application, which dose a minimum requirements check, gets the DB credentials, DB prefix and saves them, creates the db tables and so on. Now I would like to know what is the best practise to write and save the DB credentials? Write them as an array into a .php file and? Or into an XML file?
I don't think there is a best practise for this, there are so many ways people use configuration files. Some use PHP arrays, some use XML files, some use INI files, some use JSON files and I'm sure some people create proprietary formats.
What you do want to take in account is, where will you store this file. If it is in the document root, people could request it. XML/INI/JSON files are plain-text and by default, will make it easy for people to 'retrieve' the file contents. PHP will be parsed server side so just returns an empty page.
Ideally you'd store the configuration file outside of the document root, but not all webhosts allow you to do so. So I'd say, if you want to release an application people can install themselves easily, a PHP file might be the easiest way to go.
Write them as an array into a .php file. This satisfies speed (no xml parser and file touching is needed per-page), and security (.php files don't get served as text like your xml would).
I also tend to put the private.php that contains my mysql credentials in the directory above the http root, and load it like require_once("../private.php");
You are asking about setting up the environment, correct? If that is the case, then it depends on the script or build system itself. We are using Ant where such configuration is stored in build.properties. For example:
# database credentials
db.host=localhost
db.user=root
db.pass=root
db.name=db_name
This file is working copy specific and as such is not a part of our VC, however, build.properties.dist is. This way A's local settings don't override B's.
If the question is about something else, please, do tell :)