php cakePHP 3.0 上传图片
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29648335/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
cakePHP 3.0 uploading images
提问by Gilko
I want to upload images in my cakephp 3.0 app. But I get the error message:
我想在我的 cakephp 3.0 应用程序中上传图片。但我收到错误消息:
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? Because I can only find examples for cakePHP 2.x !
是否已经有一些在 cakePHP 3.0 中上传文件(一次多个文件)的示例?因为我只能找到 cakePHP 2.x 的示例!
I think I need to add a custom validation method in my ImagesTable.php? But I can't get it to work.
我想我需要在我的 ImagesTable.php 中添加一个自定义验证方法?但我无法让它工作。
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
图像控制器
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
图片添加.ctp
<?php
echo $this->Form->input('image_path', [
'label' => 'Image',
'type' => 'file'
]
);
?>
Image Entity
图像实体
protected $_accessible = [
'image_path' => true,
];
采纳答案by Bob
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
格雷茨
回答by Prassanna D Manikandan
In your view file, add like this, in my case Users/dashboard.ctp
在您的视图文件中,像这样添加,在我的情况下Users/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 webrootnamed 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 中就像一个魅力
回答by burzum
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 FileStorageout. 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 reallymany files. It works together with Imagineto process the images. You can use each alone or in combination, this follows SoC.
如果您想要一个在企业级扩展的完整解决方案,请查看FileStorage。它有一些功能我还没有在任何其他实现见过的像以确保你不会碰到在你的情况下文件系统的限制照顾真的很多文件。它与Imagine一起处理图像。您可以单独或组合使用每个,这遵循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 guideto 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);
}
}
回答by Ayoub Bousetta
/*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);
}
回答by Erdi
<?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);
}
}
}
}
}
回答by Spriz
We're using https://github.com/josegonzalez/cakephp-uploadwith 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”,但绝不是“几乎”完成”或类似的东西 - 两者都有我所有的建议,并且在我看来已经准备好生产了!