0

Hi Guys

     First of all i would like to state that i am new in php so my question might appear stupid for the geeks here.
     I want to create an image downloader in php , that is i need a textbox and a submit button.
     The user enter each url on 1 line in textbox(he can enter 30 links maximum).Then after he/she click on submit , the script takes each url , downloads it to my server and then output link 

     Can anyone of you write a small source code for me:)
     Also suggest me how do i do validation for url so that people don't transload unwanted files.I know how to do validation when uploading from computer put for url i am clueless....
3
Contributors
7
Replies
16
Views
5 Years
Discussion Span
Last Post by Khav
0

Check for file_get_contents() to get the file from remote, file_put_contents() to save the file:

$file = file_get_contents($url);
file_put_contents('/path/new_name',$file);

You can check links by using parse_url() and pathinfo(), for example to get the basename from a link use:

pathinfo(parse_url($url,PHP_URL_PATH),PATHINFO_BASENAME);

so, if the url is http://www.website.tld/images/this_image.jpg you get this_image.jpg you should also check for the mime, strip comments from the images..

0

Thanks so much cereal bro......but forgive my ignorance
Can u put the form as well.
Also the code should be able to take all url from the form
(User may not enter only 1 link)

Edited by Khav

0

you can use explode function and take a particular charatcer,symbol or word as delimiter and then based on that get array of URL's....
Then use for each loop of php and use the file_get_contents() to get the file from remote.

Hope it will suffice ur requirement.
For info about explode function click here

0

That's a lot of work, you have to sanitize data, check if the user is sending something else apart from links or if something is appended to the links, if the link format is correct, if the limit is reached, if the headers are ok (considering that headers can be spoofed)... So here it is a scrap just to get links:

<?php

function get_link($data)
{
    preg_match_all('/http(s)?:\/\/(.*)/i', $data, $matches);
    $result = array();
    foreach($matches[0] as $link)
    {
        $result[] = $link;
    }
    return $result;
}

# here place $_POST['links'] or whatever you use in the form
$form = <<<EOF
http://website.tld/image.jpg http://www.website.tld/image_with_w.jpg http://www.website.tld/image.png
http://<script>alert('hello');</script>
EOF;

print_r(get_link($form));

?>

I repeat: sanitize data, make sure your script filters malicious scripts, for example here you will get a javascript executed. Try to build your script and if you have doubts or something is not working post your code. Bye!

Edited by cereal

0

i am probably not programming form well
Anyways here is form(i execuded any validation ,need to get this working first)

<?php
foreach( $_POST['image'] as $image ) {
    $f = fopen( "/images".basename( $image ) ); //Open image file
    fwrite( $f, file_get_contents( $image ) ); //Write the contents of the web image to the newly created image on your server
    fclose( $f ); //Close the file
}     
 ?>
<form action="" method="POST" enctype="multipart/form-data" >
<textarea rows="5" cols="50" name="links"></textarea>
<input type="text" name="image"/>
<button type="submit" name="submit"></button>        

What is wrong ......please help me out
@cereal
Can u please rewrite your code so that it become of the following format
<?php
?>
Form here......(PLEASE put form as well)
Respect guys

0

Ok, just a note, if you use file_get_contents() you don't need fopen/fwrite
This is the page form:

<html>
<head>

    <title>test</title>

</head>

<body>

    <form method="post" action="grab.php">
        <textarea name="files"></textarea><br />
        <input type="submit" name="button" value="save files" />
    </form>

</body>

</html>

And this is grab.php

<?php

if($_SERVER['REQUEST_METHOD'] == 'POST')
{

    function get_link($data)
    {
        preg_match_all('/http(s)?:\/\/(.*)/i', $data, $matches);
        $result = array();
        foreach($matches[0] as $link)
        {
            $result[] = trim(strip_tags($link));
        }
        return $result;
    }

    function head($url,$length)
    {
        $h = array();
        $mimes = array(
            'image/jpeg',
            'image/pjpeg',
            'image/png',
            'image/gif'
        );

        # reference: http://www.php.net/manual/en/function.filesize.php#92462
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_NOBODY, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, true);

        // not necessary unless the file redirects (like the PHP example we're using here)
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

        $data = curl_exec($ch);
        curl_close($ch);
        if ($data === false)
        {
            return false;
        }

        else
        {
            if (preg_match('/Content-Type: (\d+)/', $data, $matches))
            {
                $h['Content-Type'] = (int)$matches[1];
            }

            if (preg_match('/Content-Length: (\d+)/', $data, $matches))
            {
                $h['Content-Length'] = (int)$matches[1];
            }

            $result[] = !isset($h['Content-Type']) ? false : in_array($h['Content-Type'],$mimes);
            $result[] = (!isset($h['Content-Length']) || ctype_digit($h['Content-Length']) || $h['Content-Length'] < $length) ? true:false;
        }            


        return in_array(true,$result,true);
    }


    function save_files($config)
    {

        $data   = $config['files'];
        $path   = $config['path'];
        $limit  = $config['limit'];
        $length = $config['length'];

        $f = get_link($data);
        $list = array();
        $c = (count($f) < $limit) ? count($f):$limit;

        if(!is_writable($path))
        {
            die('path is not writeable');
        }



        for($i = 0; $i < $c; $i++)
        {
            $file = pathinfo(parse_url($f[$i],PHP_URL_PATH));

            if($file['basename'] == true)
            {

                # check headers
                $h = head($f[$i],$length);
                if($h == true)
                {
                    $remote_data = file_get_contents($f[$i]);

                    # check if file exists and, in case, rename it
                    if(!file_exists($path.$file['basename']))
                    {
                        $name = $file['basename'];
                    }
                    else
                    {
                        $random_code = '_'.mt_rand();
                        $name = $file['filename'].$random_code.'.'.$file['extension'];
                    }

                    # save file
                    file_put_contents($path.$name,$remote_data);



                    # check file
                    if(getimagesize($path.$name) == false || filesize($path.$name) > $length)
                    {
                        unlink($path.$name);
                        $name = $name . ' not saved';
                    }

                }

                else
                {
                    $name = $file['basename'] . ' mime not allowed';
                }
            }

            else
            {
                $name = 'input n. '.$i.' is not valid';
            }

            $list['files'][] = $name;
        }

        return $list;
    }


    $config = array(
        'files'     => $_POST['files'],
        'path'      => $_SERVER['DOCUMENT_ROOT'].'/images/',
        'limit'     => 30,
        'length'    => 1024 # 1MB in bytes
    );



    # output
    echo '<pre>';
    print_r(save_files($config));
    echo '</pre>';

}
else
{
    die('no allowed access');
}

?>

Inside grab.php there is a $config array where you set the parameters for the functions above:

$config = array(
    'files'     => $_POST['files'],
    'path'      => $_SERVER['DOCUMENT_ROOT'].'/images/',
    'limit'     => 30,
    'length'    => 1024 # 1MB in bytes
);

limit deals with links, if more than 30 are submitted, then only the first 30 will be downloaded, the length is about the size limit for each file, this check is done by checking the headers (function head()) and by using filesize() after the donwload is completed.

At the moment each link needs to be prefixed by http/https. Consider this as an example, do not use this script in production, it needs to be improved. Bye!

Edited by cereal

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.