I am developing the server side php code of a mobile application using PHP with code igniter. As of now, I would like to allow users to upload images to Amazon S3 to and further allow the user to retrieve the Amazon Cloud Front url of the image that they uploaded. However, I am stuck on the image uploading part of the code. I currently get post input parameters the following way:
$userName = $this->input->post('userName');
if (!empty($userName))
{
...
}
When I search on google, all I find are scripts on how to upload images from multipart forms for example, or forms in general: Like in this link, for example
We do not use any form at this point in our app. Is there any other way to do so in php+codeigniter? Is there a similar CI way to get images from post?
EDIT: We are also thinking of uploading the images directly from our application to Amazon S3 and then storing the amazon s3 url in our database, which would also reduce traffic to our server.
Any thoughts?
Check out CodeIgniter's file upload class.
Related
I need help on how to upload multiple files on Amazon S3. So basically I have three input fields for files upload, two inputs will take 10-20 pictures and last input is only one for one image and upload them to Amazon S3 when a form is submitted.
The form that I'm using for uploading images:
I have a bucket and everything, what I need is some kind of solution to upload multiple images to Amazon S3.
I'm using PHP as my backend and for now, images are stored on hosting when a form is submitted. But I will have more then 150gb of images uploaded every month and I need S3 for hosting those images.
When I connect the form with Amazon S3 and try to upload more than one image, I get this message "POST requires exactly one file upload per request.".
Here is the NodeJS code which will give you an idea on how to upload all the files and then send a response back to the UI when the upload is complete.
I am using promises and the promise.all() method which will resolve all promises.
I am also using multer for Node.JS which handles the files that I received from the UI.
app.post('/uploadMultipleFiles',upload.array('file', 10),function(req,res){
var promises=[];
for(var i=0;i<req.files.length;i++){
var file = req.files[i];
promises.push(uploadLoadToS3(file));
}
Promise.all(promises).then(function(data){
res.send('Uploadedd');
}).catch(function(err){
res.send(err.stack);
})
})
function uploadLoadToS3(ObjFile){
var params={
ACL :'public-read',
Body : new Buffer(ObjFile.buffer),
Bucket:'ascendon1',
ContentType:ObjFile.mimetype,
Key:ObjFile.originalname
}
return s3.upload(params).promise();
}
S3 is highly scalable and distributed storage.
If you have those images locally in your machine you can simply use
aws s3 sync local_folder s3://bucket_name/
https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html
cli takes cares of syncing the data.
You can also configure how much parallelism you want on the cli with the configuration settings.
https://docs.aws.amazon.com/cli/latest/topic/s3-config.html
You can also do this programmatically if that is going to be a continuous data movement.
EDIT1:
Only one file can be uploaded from the UI at one time.
You can sequence them via javascript and upload one at a time.
If you want to take it to the backend you can do so,
https://w3lessons.info/2013/09/06/jquery-multiple-file-upload-to-amazon-s3-using-php/
Hope it helps.
I am creating an API-centric web application using PHP. I have read a lot of articles on API-centric arhitecture and design, but I have a problem related to file uploads.
Suppose I have an image and I want to upload it to the API server. How should I upload that image and how then to receive the link to that image?
Here is how I want to create it now:
Select an image using <input type="file"> on client www.domain.com
Upload it to the www.domain.com using POST with multipart/form-data
Send this image with PUT/POST API call to the api.domain.com
api.domain.com will save this image to another server like static.domain.com and will store image's id in the database
Then, when I will need this image, I can use GET API call to the api.domain.com and I will receive image's url (something like static.domain.com/image.jpg)
Aditional questions:
Is this approach the right one or I am doing completely wrong?
Will I need an aditional server to store uploaded files if my application will be small, or I can store files right on the API server?
If I will store images on same server as API server, won't it be strange if image urls will look like api.domain.com/image.jpg?
P.S: We can skip a lot of API-related things as I need only an idea on how to deal with file uploads.
You haven't really said what kind of API that you are going to be implementing here, so I assume that it is just a restful API.
Is this approach the right one or I am doing completely wrong?
No, I wouldn't say you're doing it wrong. You would essentially send the file using POST.
Will I need an aditional server to store uploaded files if my application will be small, or I can store files right on the API server?
Yes, it will allow you to store this on the same server, I don't see why not. I doubt that you will use a lot of storage, if the application is small.
If I will store images on same server as API server, won't it be strange if image urls will look like api.domain.com/image.jpg?
The api.domain.com/image.jpg technically is just the URL that you connect to the API with and GET/POST data. It does not mean the file is going to be that URL. The API could return like:
{
type: "IMG",
id: "1",
url: "example.com/uploads/image.jpg"
}
I hope this this helps, even a little!
I'm currently porting a webservice I've built to work with Google App Engine. One of the main functions in the webservice is to upload an image (a profile picture, for example). Currently what I do is:
Authenticate the user who wants to upload the image using his unique API KEY and other data.
Upload the file, give it a unique name and store the name of the file inside the user's row in the mysql database.
Now in order to port the file upload to App Engine I'm using Google Cloud Storage and following this tutorial:
https://cloud.google.com/appengine/docs/php/googlestorage/user_upload
I'm trying to get the file upload to work with my Android app the following way:
The user makes a request, the webservice authenticates him and sends in response the upload url created by CloudStorageTools::createUploadUrl.
The user uploads the image to this URL
Now heres the problem: After the upload is done, a POST is made to the given php file in createUploadUrl (I quote from google's docs) with the uploaded file. But how can this script know who uploaded the file it got? I can't pass any parameters indicating who uploaded the file to createUploadUrl so I can't insert the file name to a user in the Cloud SQL database, so now theres only a file not associated with anything in Cloud Storage.
Any hints? Am I missing something?
I'm posting this as a separate answer because a) it's different approach than the first answer, and b) I'd advocate for my other answer over this one because I think it's best to let GAE handle auth. However, I think you can do what you're trying to do this way:
Instead of routing a singular URL to your upload handler, use a regex match like this in your app.yaml to route any matching URLs to your handler:
handlers:
- url: upload_handler/(.*)
script: my-php-script-that-uploads-stuff.php
Then when invoking createUploadURL, simply pass in your API_KEY after the 'upload_handler/' as a query argument, e.g.
$upload_url = CloudStorageTools::createUploadUrl(sprintf('/upload_handler/?API_KEY=%s', $API_KEY), $options);
Then in my-php-script-that-uploads-stuff.php:
parse_str(parse_url($_SERVER['REQUEST_URI'])['query'])
This will parse the request URL to get the query string and then parse the query string, populating the value of API_KEY with the value passed in the URL in your local scope.
I just tested this pattern of extracting stuff from the request URL in a php script in with dev_appserver and it worked.
I think you can do this by using the google appengine users service in your php script.
From the link above, from the Overview page of the users service, here's how you get the current user:
use google\appengine\api\users\User;
use google\appengine\api\users\UserService;
$user = UserService::getCurrentUser();
I'm fairly new with CakePHP and images so bear with me. You can assume I'm using the latest version.
I'm trying to build an Android application which can display images retrieved from the server.
Suppose I have an image in the assets folder called football.jpg. How would I store this in the database and then how would I output this to the Android application? Do I send only the link or do I send the whole image over? If it is just the link, does this mean I would have to reconnect to the server with the link and then get the image? Sorry if this doesn't make sense. Still trying to get my head around it.
Just a word of caution, it's probably better to store the file on the server's file system and store the path to the file in the database. The reason behind this is that BLOBs are stored in a different area on the file system to all your other typical data and in terms of retrieval, its not a great deal faster.
Here's a link to what I mean: Store pictures as files or in the database for a web app?
With regards to returning it to your Android app, you can send files in the response object (http://book.cakephp.org/2.0/en/controllers/request-response.html#cake-response-file):
public function sendFile($id) {
$file = $this->Attachment->getFile($id);
$this->response->file($file['path']);
//Return reponse object to prevent controller from trying to render a view
return $this->response;
}
This should give you finer control over what files are returned to your client.
I'm building a MYSQL database driven website on a AWS EC2 instance. Users can submit their data and we will automatically create a web page for them. The webpage will display their submitted data including a photo. Upon original submission of the user's data, we store the photo in S3 using AWSSDKforPHP. When their information is approved by an administrator a webpage is created via a php script.
I've tried the method of generating a signed url. This however requires a expiration time. Is there a way around this? It also includes your access and secret key in the request. Not sure if that is the most secure way to do things. I'd like the method to be as secure as possible so I don't want to make the bucket public. Unless there is a way to make the stored images available only for viewing.
What's the best method to use in a situation like this? Thanks for your help!!
Basically URLs to amazon S3 buckets are s3.amazonaws/bucket_name/key_name all you need to do is make sure the content on those buckets is publicly available and that mime type for those keys is indeed image (image/jpeg or image/png)
I used this web tool to manage my site. I opend my bucket just to its ip and now i can control the restriction from the tool, for the basic viewer I gave read access only