Laravel - 需要在视图中对字符串运行函数

时间:2014-11-20 03:00:03

标签: laravel laravel-4

在foreach循环运行时,我需要在视图中格式化从控制器传递的字符串。 例如:

Controller:

class MyController {
public function index()
{
    $model = Events::all();
    return View::make('foo.index')->with('model', $model);
}

View:

@foreach($model as $item)
<div>{{$model->timestamp}}</div>
@endforeach`

这是棘手的部分;我希望在回显它之前运行一些格式化选项。例如,我需要从法语的时间戳中反映几个月。由于我试图避免在视图中使用任何代码,我在哪里放这个以及如何调用它?

格式化示例:

$month = date_parse($model->timestamp);
switch ($month['month']) {
      case '1':
        $month = 'Janvier';
        break;
      case '2':
        $month = 'Février';
        break;
      ...
    }

我知道这会有用,但显然是错误的代码练习:

@foreach($model as $item)
$month = date_parse($item->timestamp);
switch ($month['month']) {
      case '1':
        $month = 'Janvier';
        break;
      case '2':
        $month = 'Février';
        break;
      ...
    }
<div>{{ $month }}</div>
@endforeach`

任何帮助或提示将不胜感激!注意:我知道通常你会在控制器中处理格式化,但是因为我正在运行,我不能预先格式化&#34;在我运行foreach循环之前的输出,我在这里有点关于最佳惯例。

谢谢!

3 个答案:

答案 0 :(得分:1)

在显示之前格式化数据的一个选项是通过定义名为getXXXAttribute的函数在模型中处理它,其中XXX是表的列的名称。

假设您要在其中一个模型中格式化名为created_at的属性。所以在那个模型中你可以定义一个这样的函数:

/**
 * Return creation date in Australian format, i.e. dd/mm/YYYY.
 *
 * @param $value
 * @return bool|string
 */
public function getCreatedAtAttribute($value)
{
    return date('d/m/Y H:i:s',strtotime($value));
}

请注意,此类函数的命名约定使用camelCase。

当您在视图中打印$ model-&gt; created_at时,数据已经过格式化。

回到您的场景,您可以在模型中定义函数getTimestampAttribute(),然后将所有格式化逻辑放入其中。

在某些情况下,如果您希望同时拥有原始数据和格式化数据,则可以在模型中再添加一个属性。例如:

protected  $appends = array('parsed_timestamp');

public function getParsedTimestampAttribute()
{
    $original = $this->attributes['timestamp'];
    // process original timestamp...
}

在您的视图中,只需以这种方式访问​​此新属性:$ model-&gt; parsed_timestamp。

供您参考,这里是official document

顺便说一句,你可能想在app / lang中构造一个文件来处理i18n问题,摆脱对法语字符串的硬编码。

希望这有帮助!

答案 1 :(得分:1)

正如Carter所提到的,您可以在模型中定义函数。这是一个更具体的方法:

在您的模型中添加

public function getLocalizedMonth($locale = 'fr_FR')
{
    setlocale(LC_TIME, $locale);

    // for the column "created_at"
    $month = strftime("%B", $this->created_at->timestamp);

    // or for your column "timestamp"
    //$month = strftime("%B", $this->timestamp->timestamp);

    // set back to default 'en_US'
    setlocale(LC_TIME, 'en_US');

    return $month;
}

“created_at”作为Carbon的实例处理。在模型中使用以下函数来处理列“timestamp”

public function getDates()
{
    return array('created_at', 'updated_at', 'timestamp');
}
在您的视图中使用

for french {{ $item->getLocalizedMonth() }}

或者荷兰{{ $item->getLocalizedMonth('nl_NL') }}

<强>备注

您问题中的视图应如下所示,因为我认为您需要$item的时间戳:

@foreach($model as $item)
    <div>{{ $item->timestamp }}</div>
@endforeach

最终使用新功能:

@foreach($model as $item)
    <div>{{ $item->getLocalizedMonth() }}</div>
@endforeach

setlocale() 的PHP手册说:

  

警告每个进程维护区域设置信息,而不是每个线程。如果您在Windows上的IIS,HHVM或Apache等多线程服务器API上运行PHP,则在脚本运行时可能会遇到区域设置的突然更改,尽管脚本本身从未调用过setlocale()。这是因为其他脚本同时在同一进程的不同线程中运行,使用setlocale()更改了进程范围的语言环境。

最后但并非最不重要

在Windows机器上,$locale字符串可能会有所不同:“fr-FR”“nl-NL”

答案 2 :(得分:0)

如果这是唯一需要法语的东西,我可能会扩展Blade并可能添加一个@frenchMonth指令或其他东西,看一下这个例子from the docs,否则,我会看一下使用setlocalestrftime函数而不是date(),更多关于here


以下示例创建了一个@datetime($var)指令,只需在->format()上调用$var

Blade::extend(function($view, $compiler)
{
    $pattern = $compiler->createMatcher('datetime');

    return preg_replace($pattern, '$1<?php echo $2->format(\'m/d/Y H:i\'); ?>', $view);
});