我有一个关于 Pimple 和动态构造函数注入(inject)的问题。
假设我有一个 MVC 框架,我想做一些类似图片上传的事情。这样做的半 DI 方式是这样的:
class ImageUploadController
{
public function upload()
{
$targetImage = new Image(1920, 1080, 75, 'jpg', 'save/path');
$imageSaver = new JPEGImageSaver($targetImage);
$imageUploader = new ImageUploader($imageSaver);
$imageUploader->upload('myUploadfield');
}
}
基本上,Image 是我要创建和保存的图像属性的简单容器。 JPEGImageSaver 利用 imagecreatefromjpeg()、imagecopyresized() 和 imagejpeg() 以及 的属性code>Image 对象以及上传临时图像的属性,以保存上传图像的新安全版本。 ImageUploader 与 JPEGImageSaver 交互以安全地存储上传的图像。
问题是我有三个与 Controller 紧密耦合的类,我试图避免这种情况的方法是使用 Pimple,然后将 Pimple 传递给 Controller 。
class ImageUploadController
{
public function upload()
{
$targetImage = $this->app['Image'];
$targetImage->setWidth(1920);
$targetImage->setHeight(1080);
$targetImage->setQuality(75);
$targetImage->setExtension('jpg');
$targetImage->setSavePath('save/path');
$imageSaver = $this->app['JPEGImageSaver'];
$imageSaver->setTargetImage($targetImage);
$imageUploader = $this->app['ImageUploader'];
$imageUploader->setImageSaver($imageSaver);
$imageUploader->upload('myUploadField');
}
}
但如您所见,使用 Pimple 将依赖项注入(inject)我的 Controller 使它们的使用比以前更复杂。主要问题是我在 Pimple 中看不到在请求期间为对象设置构造函数值的方法,因此需要一组用于 Image 对象的 setter。
这个问题有通用的解决方案吗?我考虑过将 Pimple 包装在一个解析容器中,让我可以传递构造函数参数,但问题是我的 IDE 不会指示应如何通过智能感知构建各种对象。我也有点怀疑 $this->app['something'] 甚至让我的 Controller 变得更加可测试。
Controller 是否需要可测试?如果是这样,我可以将 Image 对象视为值对象吗?
有什么想法吗?
最佳答案
疙瘩是一个容器,用来储存值(value)或服务。应用程序要求 Pimple 检索服务,例如 session 对象。
如果在整个应用程序中使用具有精确定义的图像类,
<?php
$targetImage = new Image(1920, 1080, 75, 'jpg', 'save/path');
然后你可以让 Pimple 存储这个定义。
<?php
// define image service
$container['image'] = function ($c) {
return new Image(1920, 1080, 75, 'jpg', 'save/path');
};
如果您的应用程序中有不同的图像尺寸,您可以这样做:
<?php
// define image service
$container['bigImage'] = function ($c) {
return new Image(1920, 1080, 75, 'jpg', 'save/path');
};
$container['smallImage'] = function ($c) {
return new Image(200, 200, 75, 'jpg', 'save/path');
};
您可以更进一步,存储 Image 类的参数并重新使用它们。
<?php
$container['imageParams'] = [
'width' => 1920,
'height' => 1080,
'type' => 'jpg',
'quality' => 75
];
// define image service
$container['image'] = function ($c) {
$image = $c['imageParams'];
return new Image($image['width'],
$image['height'],
$image['quality'],
$image['type'],
'save/path'
);
};
目前在 Pimple 中,您无法在检索服务时传递参数:
<?php
$this->app['image'](1920, 1080, 75, 'jpg', 'save/path');
您需要扩展 Pimple 才能实现此功能。
但是,您可以在您的 Controller 类中创建一个工厂方法,该方法将修改存储在 Pimple 中的图像参数,然后调用图像服务以使用您的特定参数创建图像对象,然后将存储的参数恢复为原始值.
<?php
class ImageUploadController {
protected function imageFactory($width, $height, $type, $quality) {
// Store original parameters
$origin = $this->app['imageParams'];
// Override the original parameters
$this->app['imageParams']['width'] = $width;
$this->app['imageParams']['height'] = $height;
$this->app['imageParams']['quality'] = $quality;
$this->app['imageParams']['type'] = $type;
// Get image class
$image = $this->app['image'];
// Rest image parameters
$this->app['imageParams'] = $origin;
return $image;
}
public function upload()
{
$targetImage = $this->imageFactory(1920, 1080, 75, 'jpg');
}
}
关于php - 疙瘩和动态构造函数注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20309760/
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。
有没有办法在Ruby中动态创建数组?例如,假设我想遍历用户输入的书籍数组:books=gets.chomp用户输入:"TheGreatGatsby,CrimeandPunishment,Dracula,Fahrenheit451,PrideandPrejudice,SenseandSensibility,Slaughterhouse-Five,TheAdventuresofHuckleberryFinn"我把它变成一个数组:books_array=books.split(",")现在,对于用户输入的每一本书,我想用Ruby创建一个数组。伪代码来做到这一点:x=0books_array.
我今天看到了一个ruby代码片段。[1,2,3,4,5,6,7].inject(:+)=>28[1,2,3,4,5,6,7].inject(:*)=>5040这里的注入(inject)和之前看到的完全不一样,比如[1,2,3,4,5,6,7].inject{|sum,x|sum+x}请解释一下它是如何工作的? 最佳答案 没有魔法,符号(方法)只是可能的参数之一。这是来自文档:#enum.inject(initial,sym)=>obj#enum.inject(sym)=>obj#enum.inject(initial){|mem
我想在IRB中浏览文件系统并让提示更改以反射(reflect)当前工作目录,但我不知道如何在每个命令后进行提示更新。最终,我想在日常工作中更多地使用IRB,让bash溜走。我在我的.irbrc中试过这个:require'fileutils'includeFileUtilsIRB.conf[:PROMPT][:CUSTOM]={:PROMPT_N=>"\e[1m:\e[m",:PROMPT_I=>"\e[1m#{pwd}>\e[m",:PROMPT_S=>"FOO",:PROMPT_C=>"\e[1m#{pwd}>\e[m",:RETURN=>""}IRB.conf[:PROMPT_MO
我需要从json记录中获取一些值并像下面这样提取curr_json_doc['title']['genre'].map{|s|s['name']}.join(',')但对于某些记录,curr_json_doc['title']['genre']可以为空。所以我想对map和join()使用try函数。我试过如下curr_json_doc['title']['genre'].try(:map,{|s|s['name']}).try(:join,(','))但是没用。 最佳答案 你没有正确传递block。block被传递给参数括号外的方法