将图像存储在数据库中具有唯一名称和路径的文件夹中

时间:2012-11-15 15:35:11

标签: php image storage directory

我通过json在php文件中获取图片编码数据。我的要求是将服务器中的图像存储在一个文件夹中,前提是每个图像都应分配一个唯一的名称。我对如何将图像存储在具有唯一名称的文件夹中产生了很多疑问,然后再次将图像的路径存储在数据库中。我已经看到了几个StackOverflow问题和在线资源,但无法清楚地了解它们。这个问题对于那些从事PHP工作的人来说似乎很简单。但作为PHP的新手和Android开发人员,我无法理解那些不太详细的答案。所以,如果有人可以帮我处理代码片段和解释,我真的很感激。我试着尽可能清楚地对问题和代码进行解释。如果有任何错误,请放轻松。以下是我尝试过的代码,并在某些方面陷入困境。提前谢谢..

    <?php
    $response = array();

    // check for required fields
    if (isset($_POST['mailid']) && isset($_POST['category']) && isset($_POST['description']) && isset($_POST['contactNum']) && isset($_POST['lookingto']) && isset($_POST['image'])) {

        $usermail = $_POST['mailid'];
        $category = $_POST['category'];
        $description = $_POST['description'];
        $contactNum = $_POST['contactNum'];
        $lookingto = $_POST['lookingto'];
        $base=$_POST['image'];

        $binary=base64_decode($base);

        $folder = "images/"; // This is my folder "images" in which pics have to be stored.

        $file = fopen('storepic.jpg', 'wb');  // Here I have to give name dynamically to each pic provided that should be unique. Here I mentioned pic name as storepic.jpg, a static name.

        fwrite($file, $binary);

        fclose($file);

        // include db connect class
        require_once __DIR__ . '/db_connect.php';

        // connecting to db
        $db = new DB_CONNECT();

        // mysql inserting a new row
        $result = mysql_query("INSERT INTO details(usermail, category, description, contactnumber,posting_for) VALUES('$usermail', '$category', '$description','$contactNum','$lookingto')");

//// Even after giving dynamic name how can we store the path of the dynamic named image into database in the above query. For that what should be done here..

        // check if row inserted or not
        if ($result) {
            // successfully inserted into database
            $response["success"] = 1;

            // echoing JSON response
            echo json_encode($response);
        } else {
            // failed to insert row
            $response["success"] = 0;


            // echoing JSON response
            echo json_encode($response);
        }
    } else {

        $response["success"] = 0;


        // echoing JSON response
        echo json_encode($response);
    }
    ?>

即使在其他php文件中,我也是通过select查询检索数据。我能够获得我插入的正常数据可以在Android客户端应用程序上获取它。但是又如何从路径获取图像以便以后转换为base64编码数据然后作为json响应回显..

注意: - 我的用户界面不是表单。这是一个Android UI ..

2 个答案:

答案 0 :(得分:2)

    // A very basic field validation. You should really use mysqli* or PDO*.

    $fields = array(
        'usermail'    => 'mailid',
        'category'    => 'category',
        'description' => 'description',
        'contactNum'  => 'contactNum',
        'lookingto'   => 'lookingto',
        'binary'      => 'base',
    );
    $okay = true;
    foreach($fields as $var => $field)
    {
         if (!isset($_POST[$field]))
             $okay = false;
         if ('binary' == $var)
             ${$var} = base64_decode($_POST[$field]);
         else
             ${$var} = mysql_real_escape_string($_POST[$field]);
    }
    if (!$okay)
    {    
        $response["success"] = 0;
        Header("Content-Type: application/json;charset=UTF-8");
        die(json_encode($response));
    }

    $folder = "images/"; // This is my folder "images" in which pics have to be stored.

    $file   = tempnam($folder, 'image');

    $fp     = fopen($file, 'w');
    fwrite($file, $binary);    
    fclose($file);

    /* BUT WHAT IF THE FILE IS NOT JPEG?
       Then you use GD library and do:

       $gd = ImageCreateFromString($binary);
       if (!$gd)
       {
           // Abort. Image was invalid.
       }
       // Here you can even resize it.
       ImageJPEG($gd, $file, 75); // Quality 75%; useable values from 40 to 100
       ImageDestroy($gd);
    */

    ...

    $result = mysql_query("INSERT INTO details(usermail, category, description, contactnumber,posting_for) VALUES('$usermail', '$category', '$description','$contactNum','$lookingto')");

    // I assume that the above table has an unique ID. So we retrieve it
    $lastid = mysql_insert_id(); 

    rename($file, $newfile = sprintf("%s/img%08d.jpg", $folder, $lastid));

上面,不需要文件名的列名,因为名称与行ID相同:如果ID为1234,则图像为images/img00001234.jpg

否则你必须发出另一个查询:

    UPDATE details SET filename='$newfile' WHERE id = $lastid;

要检索

在所有情况下,您都会收到有关要检索的行的一些信息;至少它的ID,或者你可以插入WHERE的某些条件。例如,如果您收到用户电子邮件(并且它是唯一键),则您将使用WHERE email='...'

因此,您可以发出SELECT * FROM details WHERE...,在这些详细信息中,您会找到ID或filename字段。

在第一种情况下,您已经足够构建文件名,甚至不需要数据库查询,但请记住,任何知道该ID的人现在都可以访问该图像,这可能是无害的甚至是期望的(例如用户公共头像图像),但有时可能不是。

$lastid  = (int)$_REQUEST['id'];
$newfile = sprintf("%s/img%08d.jpg", $folder, $lastid);

请注意,语法与上述相同; (int)演员要记住,这是用户提供的信息,可能包含各种恶意软件。

在第二种情况下,您将发出WHERE并从检索到的元组中获取ID或直接获取文件名字段。

拥有图像路径,您可以将其发送给用户...如果图像在那里。只是检查。

if (!is_readable($newfile))
{
    Header('HTTP/1.0 404 Not Found')
    readfile('/path/to/beautiful/error-page.html');
    die();
}
// if you are really paranoid, or want to support different quality images,
// you can $gd = imageCreateFromJPEG($newfile); here, check it succeeded or
// send 404 / 500 error if it failed, manipulate $gd and send it along with
// ImageJPEG($gd, '', $quality); instead of the readfile() down there. With
// this approach, you'll better not send Content-Length, though. This makes
// image DOWNLOADS more awkward (you don't see "104K of 1.3M downloaded").

Header('Content-Type: image/jpeg');
Header('Content-Length: ' . filesize($newfile));
readfile($newfile);
die();

......就是这样。在调用上述内容的HTML源代码中,您可能有:

<img class="avatar" src="images.php?id=<?php echo $details['id']; ?>" />

(PHP生成HTML 需要来访问数据库并获取$details,当然)。

还有其他设置允许“调用”PHP以受保护的方式将数据库元组信息保存在_GET参数中,这样即使用户看到图像是使用

检索的
image.php?id=1234

并且知道Bob有ID 7654,但仍然无法通过将1234更改为7654来检索图像,但我不知道这是否对某人感兴趣。

使用Web浏览器,设置内容就足够了。使用Internet Explorer,您可能需要以.jpg结束文件,而这可能需要使用URL重写方案。

答案 1 :(得分:0)

    package com.example.test_image_save;

    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;

    import android.app.Activity;
    import android.content.ContentValues;
    import android.content.Context;
    import android.content.Intent;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.graphics.BitmapFactory;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Environment;
    import android.provider.MediaStore;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.TextView;
    import android.widget.Toast;

    public class MainActivity extends Activity implements OnClickListener {
    protected static TextView textView;
    protected static ImageView image1, image2;
    protected Button get_image, save_image, read_image;
    private String selectedImagePath;
    private static final int SELECT_PICTURE = 1;
    String DB_NAME = Environment.getExternalStorageDirectory() + "/test.db";
    String TABLE_NAME = "mytable";

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    image1 = (ImageView) findViewById(R.id.imageView1);
    image2 = (ImageView) findViewById(R.id.imageView2);
    textView = (TextView) findViewById(R.id.textView1);

    get_image = (Button) findViewById(R.id.get_image);
    get_image.setOnClickListener(this);

    save_image = (Button) findViewById(R.id.save_image);
    save_image.setOnClickListener(this);

    read_image = (Button) findViewById(R.id.read_image);
    read_image.setOnClickListener(this);

    }

    public void onClick(View v) {

    int id = v.getId();
    switch (id) {

    case R.id.get_image:
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(
                Intent.createChooser(intent, "Select Picture"),
                SELECT_PICTURE);
        break;

    case R.id.save_image:
        createTable();
        saveInDB();
        break;

    case R.id.read_image:
        readFromDB();
        break;
    default:
        break;

    }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_PICTURE) {
            Uri selectedImageUri = data.getData();
            selectedImagePath = getPath(selectedImageUri);
            System.out.println("Image Path : " + selectedImagePath);
            image1.setVisibility(View.VISIBLE);
            image1.setImageURI(selectedImageUri);
        }
    }
    }

    @SuppressWarnings("deprecation")
    public String getPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    int column_index = cursor
            .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
    }

    void createTable() {
    SQLiteDatabase myDb = openOrCreateDatabase(DB_NAME,
            Context.MODE_PRIVATE, null);
    String MySQL = "create table if not exists "
            + TABLE_NAME
            + " (_id INTEGER primary key autoincrement, name TEXT not null, image BLOB);";
    myDb.execSQL(MySQL);
    myDb.close();
    }

    void saveInDB() {
    SQLiteDatabase myDb = openOrCreateDatabase(DB_NAME,
            Context.MODE_PRIVATE, null);
    byte[] byteImage1 = null;
    String s = myDb.getPath();

    myDb.execSQL("delete from " + TABLE_NAME);          // clearing the table
    ContentValues newValues = new ContentValues();
    String name = "SachinImages";
    newValues.put("name", name);
    try {
        FileInputStream instream = new FileInputStream(selectedImagePath);
        BufferedInputStream bif = new BufferedInputStream(instream);
        byteImage1 = new byte[bif.available()];
        bif.read(byteImage1);
        newValues.put("image", byteImage1);
        long ret = myDb.insert(TABLE_NAME, null, newValues);
        if (ret < 0)
            textView.append("Error");
    } catch (IOException e) {
        textView.append("Error Exception : " + e.getMessage());
    }
    myDb.close();
    textView.append("\n Saving Details \n Name : " + name);
    textView.append("\n Image Size : " + byteImage1.length + " KB");
    textView.append("\n Saved in DB : " + s + "\n");
    Toast.makeText(this.getBaseContext(),
            "Image Saved in DB successfully.", Toast.LENGTH_SHORT).show();
    }

    void readFromDB() {
    byte[] byteImage2 = null;
    SQLiteDatabase myDb;
    myDb = openOrCreateDatabase(DB_NAME, Context.MODE_PRIVATE, null);
    Cursor cur = myDb.query(TABLE_NAME, null, null, null, null, null, null);
    cur.moveToFirst();
    while (cur.isAfterLast() == false) {
        textView.append("\n Reading Details \n Name : " + cur.getString(1));
        cur.moveToNext();
    }

    // /////Read data from blob field////////////////////
    cur.moveToFirst();
    byteImage2 = cur.getBlob(cur.getColumnIndex("image"));
    setImage(byteImage2);
    cur.close();
    myDb.close();
    Toast.makeText(this.getBaseContext(),
            "Image read from DB successfully.", Toast.LENGTH_SHORT).show();
    Toast.makeText(this.getBaseContext(),
            "If your image is big, please scrolldown to see the result.",
            Toast.LENGTH_SHORT).show();
    }

    void setImage(byte[] byteImage2) {
    image2.setImageBitmap(BitmapFactory.decodeByteArray(byteImage2, 0,
            byteImage2.length));
    textView.append("\n Image Size : " + byteImage2.length + " KB");
    }

    }