2

Greetings

I need to display images stored in BLOB database fields in a LISTVIEW or similar widget from Yii2

I have the actionCreate that saves the image in table named honra as a BLOB

public function actionCreate()
{
    $model = new Honra();

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        $file = UploadedFile::getInstance($model,'binaryfile');
        $model->binaryfile=$file;
        return $this->redirect(['view', 'id' => $model->id]);
    } else {
        return $this->render('create', [
            'model' => $model,
        ]);
    }
}

I also have the model named Honra

class Honra extends \yii\db\ActiveRecord{

public static function tableName()
{
    return 'honra';
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['nome', 'texto'], 'required'],
        [['texto', 'binaryfile'], 'string'],
        [['ativo'], 'integer'],
        [['nome'], 'string', 'max' => 255],
        [['fileName'], 'string', 'max' => 100],
        [['fileType'], 'string', 'max' => 50]
    ];
}

/**
 * @inheritdoc
 */
public function attributeLabels()
{
    return [
        'id' => Yii::t('app', 'ID'),
        'nome' => Yii::t('app', 'Nome'),
        'texto' => Yii::t('app', 'Texto'),
        'fileName' => Yii::t('app', 'File Name'),
        'fileType' => Yii::t('app', 'File Type'),
        'binaryfile' => Yii::t('app', 'Binaryfile'),
        'ativo' => Yii::t('app', 'Ativo'),
    ];
}

}

The images are successfully stored in the table field named binaryfile

And i need to display each blob image stored in database in a view named view2 inside a LISTVIEW or similar widget

Anyone knows what block of code i need to put in view2 and the HonraController to achieve this ??

EDIT

SOLVED

HERE IS THE CODE THAT SOLVED THE ISSUE, NOW EVERYTHING IS WORKING WELL

public function actionCreate()
{
    $model = new Honra();

     if (Yii::$app->request->isPost) {

            $model->file = UploadedFile::getInstance($model, 'file');
            $filePath = 'uploadsimg/'  . $model->file->baseName . '.' . $model->file->extension;
            $model->fileName = $filePath;
            $model->save();

            $model->file->saveAs('uploadsimg/' . $model->file->baseName . '.' . $model->file->extension);
            if ($model->load(Yii::$app->request->post()) && $model->save()) {
                return $this->redirect(Url::toRoute(['create']));
            }
        }
        return $this->render('create', ['model' => $model]);
}

MANY THANKS FOR THE HELP MIHAI

André Castro
  • 1,527
  • 6
  • 33
  • 60
  • Well you have to make another call to an action in a controller that will give you the image. That is for each image in the list. You cannot directly show it in the list I believe as html does not work that way. Why did you choose to put the images in the DB? It will make your db huge very fast, you are much better to create a unique link (maybe with a hash so people do not guess the path of other images) and just store the path in the db. – Mihai P. Dec 23 '14 at 23:42
  • More opinions on keeping the images in the db http://stackoverflow.com/questions/3748/storing-images-in-db-yea-or-nay – Mihai P. Dec 23 '14 at 23:43
  • I put the images in the db because i want a listview to store and show the name of a person and also show its photo. The photo as to appear visible from the first moment, not a link. – André Castro Dec 23 '14 at 23:48
  • So, you are telling me that it is impossible to display in a listview for each person in the database the matching photo stored as a BLOB ? – André Castro Dec 23 '14 at 23:53
  • Well, you can embed the images directly into html. See here http://www.techerator.com/2011/12/how-to-embed-images-directly-into-your-html/ – Mihai P. Dec 23 '14 at 23:56
  • But it is a wrong way of doing it. You will have no reusability of the images meaning the images will not be cached for further use. You are increasing the HTML size of the page with image code and your database will get big fast. Why not build it properly from the start, store the images on the disk, keep the path in the DB, use the images the proper way. I know it is easier to keep the images in the DB but that does not mean it is better. – Mihai P. Dec 23 '14 at 23:59
  • Yes. I will try to do as you are saying, but the only thing i know for now is how to store the images in a local folder. Don't have a clue on how to store the image path and name+extension on database field. Can you give me some help with path thing? – André Castro Dec 24 '14 at 00:02
  • It is easy, here is the official Yii documentation https://github.com/yiisoft/yii2/blob/master/docs/guide/input-file-upload.md – Mihai P. Dec 24 '14 at 00:16
  • Yes. Thats'it. I was already making it. Let's see if i can... Many thanks, as usual, Mihai. – André Castro Dec 24 '14 at 00:18
  • I put in an answer with some code too and with some suggestions. You will be up and running in no time :). – Mihai P. Dec 24 '14 at 00:24

2 Answers2

1

Here is the official documentation on Yii2 https://github.com/yiisoft/yii2/blob/master/docs/guide/input-file-upload.md It is quite simple.

some comments:
1) the pics might be private and it might be a big problem if somebody guesses the path of others. In this case you can put the file someplace NOT in the web folder. If you do this then you have to use the assets to show them assetManager->getPublishedUrl('@app/folder')?>/fav.ico
2) if the pics are not so sensitive then you can just save them someplace in the web folder.

As you can see you might have problems with uploading the same file name 2 times, as 1 will override the other. You can always rename the file, I would actually change their code to something like this

        if ($model->file && $model->validate()) {
$model->file = UploadedFile::getInstance($model, 'file');
            $filePath = 'uploads/' . hash('ripemd160', microtime()) . $model->file->baseName . '.' . $model->file->extension;
            $model->fileName = $filePath;
            $model->save();

            $model->file->saveAs('uploadsimg/' . $model->file->baseName . '.' . $model->file->extension);
            if ($model->load(Yii::$app->request->post()) && $model->save()) {
                return $this->redirect(Url::toRoute(['create']));
            }
        }
Mihai P.
  • 9,307
  • 3
  • 38
  • 49
1

The shortest way I found to display a image from a BLOB field (in a MySQL database) was using this code (in my view):

$sql = "SELECT FieldName FROM TableName"; //optional where statements etc.
$connection = Yii::$app->getDb();
$command = $connection->createCommand($sql);
$imgLogo = $command->queryScalar();
echo '<img src="data:image/jpeg;base64,'.base64_encode($imgLogo).'"/>';

Note that in this example I have only one row in the table 'TableName' as this example was used to retrieve the logo from the company. And there is only one company stored in that table.

Rob Mies
  • 11
  • 1