简体   繁体   English

cakePHP 3.0上传图片

[英]cakePHP 3.0 uploading images

I want to upload images in my cakephp 3.0 app. 我想在我的cakephp 3.0应用程序中上传图像。 But I get the error message: 但我收到错误消息:

Notice (8): Undefined index: Images [APP/Controller/ImagesController.php, line 55]

Are there already some examples for uploading files (multiple files at once) in cakePHP 3.0? 在cakePHP 3.0中是否已经有一些上传文件(一次多个文件)的例子? Because I can only find examples for cakePHP 2.x ! 因为我只能找到cakePHP 2.x的例子!

I think I need to add a custom validation method in my ImagesTable.php? 我想我需要在ImagesTable.php中添加自定义验证方法? But I can't get it to work. 但我无法让它发挥作用。

ImagesTable ImagesTable

public function initialize(array $config) {
    $validator
       ->requirePresence('image_path', 'create')
       ->notEmpty('image_path')
       ->add('processImageUpload', 'custom', [
          'rule' => 'processImageUpload'
       ])
}

public function processImageUpload($check = array()) {
    if(!is_uploaded_file($check['image_path']['tmp_name'])){
       return FALSE;
    }
    if (!move_uploaded_file($check['image_path']['tmp_name'], WWW_ROOT . 'img' . DS . 'images' . DS . $check['image_path']['name'])){
        return FALSE;
    }
    $this->data[$this->alias]['image_path'] = 'images' . DS . $check['image_path']['name'];
    return TRUE;
}

ImagesController ImagesController

public function add()
    {
        $image = $this->Images->newEntity();
        if ($this->request->is('post')) {
            $image = $this->Images->patchEntity($image, $this->request->data);

            $data = $this->request->data['Images'];
            //var_dump($this->request->data);
            if(!$data['image_path']['name']){
                unset($data['image_path']);
            }

            // var_dump($this->request->data);
            if ($this->Images->save($image)) {
                $this->Flash->success('The image has been saved.');
                return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error('The image could not be saved. Please, try again.');
            }
        }
        $images = $this->Images->Images->find('list', ['limit' => 200]);
        $projects = $this->Images->Projects->find('list', ['limit' => 200]);
        $this->set(compact('image', 'images', 'projects'));
        $this->set('_serialize', ['image']);
    }

Image add.ctp 图片add.ctp

<?php
   echo $this->Form->input('image_path', [
      'label' => 'Image',
      'type' => 'file'
      ]
   );
?>

Image Entity 图像实体

protected $_accessible = [
    'image_path' => true,
];

In your view file, add like this, in my case Users/dashboard.ctp 在您的视图文件中,像我这样添加用户/ dashboard.ctp

<div class="ChImg">
<?php 
echo $this->Form->create($particularRecord, ['enctype' => 'multipart/form-data']);
echo $this->Form->input('upload', ['type' => 'file']);
echo $this->Form->button('Update Details', ['class' => 'btn btn-lg btn-success1 btn-block padding-t-b-15']);
echo $this->Form->end();       
?>
</div>

In your controller add like this, In my case UsersController 在你的控制器中添加像这样,在我的情况下UsersController

if (!empty($this->request->data)) {
if (!empty($this->request->data['upload']['name'])) {
$file = $this->request->data['upload']; //put the data into a var for easy use

$ext = substr(strtolower(strrchr($file['name'], '.')), 1); //get the extension
$arr_ext = array('jpg', 'jpeg', 'gif'); //set allowed extensions
$setNewFileName = time() . "_" . rand(000000, 999999);

//only process if the extension is valid
if (in_array($ext, $arr_ext)) {
    //do the actual uploading of the file. First arg is the tmp name, second arg is 
    //where we are putting it
    move_uploaded_file($file['tmp_name'], WWW_ROOT . '/upload/avatar/' . $setNewFileName . '.' . $ext);

    //prepare the filename for database entry 
    $imageFileName = $setNewFileName . '.' . $ext;
    }
}

$getFormvalue = $this->Users->patchEntity($particularRecord, $this->request->data);

if (!empty($this->request->data['upload']['name'])) {
            $getFormvalue->avatar = $imageFileName;
}


if ($this->Users->save($getFormvalue)) {
   $this->Flash->success('Your profile has been sucessfully updated.');
   return $this->redirect(['controller' => 'Users', 'action' => 'dashboard']);
   } else {
   $this->Flash->error('Records not be saved. Please, try again.');
   }
}

Before using this, create a folder in webroot named upload/avatar . 在使用此功能之前,请在webroot中创建名为upload / avatar的文件夹。

Note: The input('Name Here'), is used in 注意:输入('Name Here')用于

$this->request->data['upload']['name']

you can print it if you want to see the array result. 如果要查看数组结果,可以打印它。

Its works like a charm in CakePHP 3.x 它的作品就像CakePHP 3.x中的魅力

Maybe the following would help. 也许以下内容会有所帮助。 It's a behavior who helps you to upload files very easy! 这是一种帮助您轻松上传文件的行为!

http://cakemanager.org/docs/utils/1.0/behaviors/uploadable/ http://cakemanager.org/docs/utils/1.0/behaviors/uploadable/

Let me know if you struggle. 如果你挣扎,请告诉我。

Greetz 格尔茨

Now that everyone makes advertisement for his plugins here, let me do this as well. 现在每个人都在这里为他的插件制作广告,让我也这样做。 I've checked the Uploadable behavior linked in the other question, it's pretty simple and half done it seems. 我已经检查了在另一个问题中链接的可上传行为,它非常简单,看起来已经完成了一半。

If you want a complete solution that is made to scale on enterprise level check FileStorage out. 如果您想要在企业级别上进行扩展的完整解决方案,请检查FileStorage It has some features I haven't seen in any other implementations yet like taking care of ensuring your won't run into file system limitations in the case you get really many files. 它有一些功能我还没有在任何其他实现见过的像以确保您不会在你得到真正的许多文件的情况下运行到文件系统的限制照顾。 It works together with Imagine to process the images. 它与Imagine一起处理图像。 You can use each alone or in combination, this follows SoC . 您可以单独或组合使用,这遵循SoC

It is completely event based, you can change everything by implementing your own event listeners. 它完全基于事件,您可以通过实现自己的事件侦听器来更改所有内容。 It will require some intermediate level of experience with CakePHP. 这将需要CakePHP的一些中级经验。

There is a quick start guide to see how easy it is to implement it. 有一个快速入门指南 ,看看实现它是多么容易。 The following code is taken from it, it's a complete example, please see the quick start guide, it's more detailed. 以下代码取自它,这是一个完整的例子,请参阅快速入门指南,它更详细。

class Products extends Table {
    public function initialize() {
        parent::initialize();
        $this->hasMany('Images', [
            'className' => 'ProductImages',
            'foreignKey' => 'foreign_key',
            'conditions' => [
                'Documents.model' => 'ProductImage'
            ]
        ]);
        $this->hasMany('Documents', [
            'className' => 'FileStorage.FileStorage',
            'foreignKey' => 'foreign_key',
            'conditions' => [
                'Documents.model' => 'ProductDocument'
            ]
        ]);
    }
}

class ProductsController extends ApController {
    // Upload an image
    public function upload($productId = null) {
        if (!$this->request->is('get')) {
            if ($this->Products->Images->upload($productId, $this->request->data)) {
                $this->Session->set(__('Upload successful!');
            }
        }
    }
}

class ProductImagesTable extends ImageStorageTable {
    public function uploadImage($productId, $data) {
        $data['adapter'] = 'Local';
        $data['model'] = 'ProductImage',
        $data['foreign_key'] = $productId;
        $entity = $this->newEntity($data);
        return $this->save($data);
    }
    public function uploadDocument($productId, $data) {
        $data['adapter'] = 'Local';
        $data['model'] = 'ProductDocument',
        $data['foreign_key'] = $productId;
        $entity = $this->newEntity($data);
        return $this->save($data);
    }
}
/*Path to Images folder*/
$dir = WWW_ROOT . 'img' .DS. 'thumbnail';
/*Explode the name and ext*/
                $f = explode('.',$data['image']['name']);
                 $ext = '.'.end($f);
    /*Generate a Name in my case i use ID  & slug*/
                $filename = strtolower($id."-".$slug);

     /*Associate the name to the extension  */
                $image = $filename.$ext;


/*Initialize you object and update you table in my case videos*/
                $Videos->image = $image;     
            if ($this->Videos->save($Videos)) {
/*Save image in the thumbnail folders and replace if exist */
            move_uploaded_file($data['image']['tmp_name'],$dir.DS.$filename.'_o'.$ext);

            unlink($dir.DS.$filename.'_o'.$ext);
                } 
<?php
namespace App\Controller\Component;

use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
use Cake\Network\Exception\InternalErrorException;
use Cake\Utility\Text;

/**
 * Upload component
 */
class UploadRegCompanyComponent extends Component
{

    public $max_files = 1;


    public function send( $data )
    {
        if ( !empty( $data ) ) 
        {
            if ( count( $data ) > $this->max_files ) 
            {
                throw new InternalErrorException("Error Processing Request. Max number files accepted is {$this->max_files}", 1);
            }

            foreach ($data as $file) 
            {
                $filename = $file['name'];
                $file_tmp_name = $file['tmp_name'];
                $dir = WWW_ROOT.'img'.DS.'uploads/reg_companies';
                $allowed = array('png', 'jpg', 'jpeg');
                if ( !in_array( substr( strrchr( $filename , '.') , 1 ) , $allowed) ) 
                {
                    throw new InternalErrorException("Error Processing Request.", 1);       
                }
                elseif( is_uploaded_file( $file_tmp_name ) )
                {
                    move_uploaded_file($file_tmp_name, $dir.DS.Text::uuid().'-'.$filename);
                }
            }
        }
    }
}

We're using https://github.com/josegonzalez/cakephp-upload with great success in our production app, and has done so for quite some time. 我们正在使用https://github.com/josegonzalez/cakephp-upload在我们的生产应用程序中取得巨大成功,并且已经这么做了很长时间。

Has awesome support for using "Flysystem" ( https://flysystem.thephpleague.com/ ) as well - which is abstractions from specific file system(s) - so moving from normal local file system to S3 is a no-brainer, or Dropbox or whatever place you want :-) 非常支持使用“Flysystem”( https://flysystem.thephpleague.com/ ) - 这是来自特定文件系统的抽象 - 所以从普通的本地文件系统转移到S3是一个明智的选择,或者Dropbox或你想要的任何地方:-)

You can find related (high quality) plugins on file uploading right here: https://github.com/FriendsOfCake/awesome-cakephp#files - I've used "Proffer" with success as well, and it's by no means "almost done" or anything alike - both has all my recommendations and is in my eyes production ready! 你可以在这里找到相关的(高质量)文件上传插件: https//github.com/FriendsOfCake/awesome-cakephp#files - 我也成功地使用了“Proffer”,它绝不是“差不多”完成“或类似的事情 - 都有我的所有建议,并在我眼中生产准备好了!

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

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