简体   繁体   English

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

[英]Storing the image in folder with unique name and path in database

I am getting the picture encoded data in the php file through json.我通过json获取php文件中的图片编码数据。 My requirement is to store that images in server in one folder provided each image should be assigned a unique name.我的要求是将该图像存储在服务器中的一个文件夹中,前提是每个图像都应分配一个唯一的名称。 I am getting lot of doubts on how to store the image in a folder with unique name and then again the path of the image is stored in the database.我对如何将图像存储在具有唯一名称的文件夹中然后再次将图像的路径存储在数据库中产生了很多疑问。 I have seen couple of StackOverflow questions and online sources, but couldn't get them clearly.我看过几个 StackOverflow 问题和在线资源,但无法清楚地了解它们。 This question seems simple to the ones who work on PHP.对于从事 PHP 工作的人来说,这个问题似乎很简单。 But as a newbie in php and as an Android developer, I am unable to understand that less-detailed answers.但作为 php 新手和 Android 开发人员,我无法理解那些不太详细的答案。 So, I would really appreciate if someone can help me with code snippets and explanation.因此,如果有人可以帮助我提供代码片段和解释,我将不胜感激。 I tried to keep my explanation of question and code with comments as clear as I can.我尽量保持我对问题和代码的解释和注释的清晰。 If there are any mistakes, please go easy.The following is the code that I tried and got stuck at some points.如果有任何错误,请放轻松。以下是我尝试并在某些地方卡住的代码。 Thanks in advance..提前致谢..

    <?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);
    }
    ?>

Even in other php file I am retrieving the data by select query.即使在其他 php 文件中,我也通过选择查询检索数据。 I am able to get the normal data what I inserted could get it on Android client side app.我能够获得我插入的正常数据,可以在 Android 客户端应用程序上获得它。 But then again how to get the image from the path for later converting into base64 encoded data and then echoing as json response..但是又如何从路径中获取图像以便稍后转换为 base64 编码数据,然后作为 json 响应回显..

NOTE:- My UI is not form.注意:-我的用户界面不是表单。 It's an Android UI..这是一个Android用户界面..

    // 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));

Above, you do not need a column name for the file name since the name is the same as the row ID: if ID is 1234, the image is images/img00001234.jpg .上面,您不需要文件名的列名,因为名称与行 ID 相同:如果 ID 为 1234,则图像为images/img00001234.jpg

Otherwise you have to issue another query:否则,您必须发出另一个查询:

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

To retrieve检索

In all cases you'll receive some information about the row to retrieve;在所有情况下,您都会收到有关要检索的行的一些信息; at a minimum its ID, or anyway some conditions you can plug into a WHERE .至少它的 ID,或者无论如何你可以插入WHERE一些条件。 If, for example, you get the user email (and it is a unique key), you'll use WHERE email='...' .例如,如果您收到用户电子邮件(并且它是一个唯一键),您将使用WHERE email='...'

So you will be able to issue a SELECT * FROM details WHERE... and among these details you will find either the ID, or the filename field.因此,您将能够发出SELECT * FROM details WHERE...并且在这些详细信息中,您将找到 ID 或filename段。

In the first case you've got enough to build the filename and do not even need the database query, but remember that anyone knowing the ID can now access the image , this may be harmless or even desired (eg user public avatar image) but sometimes it might not be.在第一种情况下,您已经足够构建文件名,甚至不需要数据库查询,但请记住,任何知道 ID 的人现在都可以访问图像,这可能是无害的甚至是需要的(例如用户公共头像图像)但是有时可能不是。

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

Note that the syntax is the same as above;注意语法和上面一样; the (int) cast is to remember that this is user-supplied information and could contain all sorts of malicious crud. (int) cast 是要记住这是用户提供的信息,可能包含各种恶意 crud。

In the second case you'll issue a WHERE and fetch either the ID or directly the filename field from the retrieved tuple.在第二种情况下,您将发出WHERE并从检索到的元组中获取 ID 或直接获取文件名字段。

Having the image path, you can send it to the user... if the image is there.拥有图像路径,您可以将其发送给用户......如果图像在那里。 Just checking.只是检查。

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();

...and that's it. ......就是这样。 In the HTML source calling the above, you might have:在调用上面的 HTML 源代码中,您可能有:

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

(the PHP generating that HTML needs to access the database and fetch $details , of course). (当然,生成 HTML 的 PHP需要访问数据库并获取$details )。

There are other setups that allow the "calling" PHP to save the database tuple information in the _GET parameters in a protected way, so that even if the user sees that the image was retrieved with还有其他设置允许“调用”PHP 以受保护的方式将数据库元组信息保存在 _GET 参数中,这样即使用户看到图像是用

image.php?id=1234

and knows that Bob has ID 7654, still she can't retrieve the image by changing 1234 into 7654, but I don't know whether this is of interest to someone.并且知道Bob的ID是7654,但她还是无法通过将1234更改为7654来检索图像,但我不知道这是否有人感兴趣。

With Web browsers, setting the content is enough.对于 Web 浏览器,设置内容就足够了。 Using Internet Explorer you might need the file to end in .jpg , and this in turn might require using a URL Rewriting scheme.使用 Internet Explorer,您可能需要文件以.jpg结尾,而这反过来可能需要使用 URL 重写方案。

    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");
    }

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM