Php 在数组中使用变量

Php 在数组中使用变量,php,Php,我借用了beautiful类,它将常规DateTime转换为“ago格式” 我正在开发多语言网站,希望用变量替换年前,年前,月前 代码示例: 是否可以在不使用替换方法的情况下执行此操作 显然,这不起作用: 'm'=>数组('1'.$month\u前,%d'.$month\u前), 有什么帮助吗?您不需要撇号的地方有撇号 你的目标是: $month_ago = 'month ago'; $months_ago = 'months ago'; //Further on within the

我借用了beautiful类,它将常规DateTime转换为“ago格式”

我正在开发多语言网站,希望用变量替换
年前
年前
月前

代码示例:
是否可以在不使用替换方法的情况下执行此操作

显然,这不起作用:

'm'=>数组('1'.$month\u前,%d'.$month\u前),


有什么帮助吗?

您不需要撇号的地方有撇号

你的目标是:

 $month_ago = 'month ago';
 $months_ago = 'months ago';

//Further on within the array
'm' -> array('1 '.$month_ago, '%d '.$months_ago);

如果该类不扩展
DateTime
,它将更加有用。它唯一能做的就是格式化一个日期,它根本没有理由成为一个日期。它可以很容易地根据需要创建一个
日期时间
,并处理它,而不是
$this

如果您进行了此修改(并将类适当地重命名为,例如,
datetimedifformatter
),那么所有的可能性都会突然出现:您可以将一个参数传递给确定要使用的语言的构造函数,或者更好地传递一些对i18n组件的引用。例如,你可以

// I have no idea why this was protected, and probably the class author did not as well
private $strings = array(
    'y' => array('years_ago_1', 'years_ago_n'),
    // etc etc
);

最后,假设可以将本地化字符串的格式硬编码为“X分钟前”或类似的格式,这是一个非常糟糕的想法。数字必须是格式字符串的一部分,因为在许多文化中,它不在“多久以前”部分之前

更新
我修改了伊利亚的候选方案,使其符合上述建议;结果是。

基于建议的想法,我终于找到了一个用于返回时差的多语言解决方案

请对我温和一点,因为我是面向对象风格编程的完全初学者,这实际上是我的第一项任务。如果你留下评论或建议,我会非常高兴

特别感谢乔恩,很抱歉我不能体现你所有的想法。我接受你的答案,因为它有非常好的建议和解释

描述
  • 在我的数据库中,我添加了时间字段,该字段表示每个上传的Unix时间戳格式视频的创建时间,例如
    1345284190

    此时间戳会像
    newcreationtime('@'.$timestamp)
    一样传递给构造函数

  • 我有一个特殊的功能,可以循环浏览每个视频并插入
    例如:视频是27天前添加的

  • 我最终通过在上使用Cokidoo提供的一个漂亮的示例实现了这一点,并添加了对多语言网站的支持,用从语言文件派生的任何文本替换了几年前的、
    几个月前的
    几天前的

    扭捏
  • 我已将用英语编写的初始值(即:年前、月前、日前等)(以便能够在多语言网站中使用)更改为易于处理的值,例如:
    year\u ago
    month\u ago
    day\u ago

  • 然后我分解了返回输出的初始
    $value
    变量,例如:1年前、1个月前、1天前,并按照建议在return
    sprintf
    中使用

  • 最后,我添加了
    getLocalized
    函数,将这个类与我的语言文件连接起来

  • 这是最后一个不会抛出警告的代码(已启用警告;PHP版本5.4.6)
    我已将类名从
    Cokidoo\u DateTime
    重命名为
    creationTime

    class creationTime extends DateTime {
    
        private $strings = array(
            'y' => array('1 year_ago', '%d years_ago'),
            'm' => array('1 month_ago', '%d months_ago'),
            'd' => array('1 day_ago', '%d days_ago'),
            'h' => array('1 hour_ago', '%d hours_ago'),
            'i' => array('1 minute_ago', '%d minutes_ago'),
            's' => array('just_now', '%d seconds_ago'),
        );
    
       private function getLocalized($string) {
    
            global $lang;
    
            $string == 'year_ago' ? $string = $lang['global.year_ago'] : null;
            $string == 'years_ago' ? $string = $lang['global.years_ago'] : null;
            $string == 'month_ago' ? $string = $lang['global.month_ago'] : null;
            $string == 'months_ago' ? $string = $lang['global.months_ago'] : null;
            $string == 'day_ago' ? $string = $lang['global.day_ago'] : null;
            $string == 'days_ago' ? $string = $lang['global.days_ago'] : null;
            $string == 'hour_ago' ? $string = $lang['global.hour_ago'] : null;
            $string == 'hours_ago' ? $string = $lang['global.hours_ago'] : null;
            $string == 'hour_ago' ? $string = $lang['global.hour_ago'] : null;
            $string == 'hours_ago' ? $string = $lang['global.hours_ago'] : null;
            $string == 'minute_ago' ? $string = $lang['global.minute_ago'] : null;
            $string == 'minutes_ago' ? $string = $lang['global.minutes_ago'] : null;
            $string == 'just_now' ? $string = $lang['global.just_now'] : null;
            $string == 'seconds_ago' ? $string = $lang['global.seconds_ago'] : null;
    
            return $string;
        }
    
        /**
         * Returns the difference from the current time in the format X time ago
         * @return string
         */
    
       public function __toString() {
            $now = new DateTime('now');
            $diff = $this->diff($now);
            foreach($this->strings as $key => $value){
                if( ($text = $this->getDiffText($key, $diff)) ){
                    return $text;
                }
            }
            return '';
        }
    
        /**
         * Try to construct the time diff text with the specified interval key
         * @param string $intervalKey A value of: [y,m,d,h,i,s]
         * @param DateInterval $diff
         * @return string|null
         */
        protected function getDiffText($intervalKey, $diff){
            $pluralKey = 1;
            $value = $diff->$intervalKey;
            if($value > 0){
                if($value < 2){
                    $pluralKey = 0;
                }
                $value = explode(' ', sprintf($this->strings[$intervalKey][$pluralKey], $value) );          
                return sprintf('%d %s', implode(array_slice($value, 0)), $this->getLocalized(implode(array_slice($value, 1))));
            }
            return null;
        }
    }
    

    可能是这样吗?@Ostrovski谢谢你,这是可能的。其他解决方案?是的,没有理由使用
    protected
    ,但为什么我们不能在类内使用正常的解决方案,比如我称之为不起作用的解决方案?使用
    sprintf
    是可以的,但我认为它并不完美?这门课的作者提出使用
    gettext
    ,我对此也不太满意。。你觉得还有别的吗?我有英语、西班牙语、意大利语、法语、德语、俄语和日语,看来
    “X分钟前”
    对所有这些都有效,请检查;)@伊莉亚罗斯托夫采夫:你的建议行不通,如果真的行了,那就无法扩大规模
    sprintf
    是99%的PHP本地化库所使用的,包括您链接到的原始类——非常好。如果你想得到更多的想法,看看著名的PHP框架是如何解决本地化问题的。好吧,Jon!非常感谢+1.我会等一会儿,如果没有人想出一些不寻常的解决办法,我会接受你的回答!乔恩,谢谢你的建议和一切。基于你的想法,我终于达到了预期的效果!请看一看我自己的答案,并发表评论,以防你会说什么或提供什么!;)谢谢,但这是课堂的一部分,不是这样的!我根据我最初的想法调整了你的解决方案;请参阅我的答案更新,以获取一个实时示例。它并不比上面的更好,但它的结构更好。我只是喜欢它!太棒了!谢谢!!;)我已经更新了我的答案!
    return sprintf($localizer->get_string($this->strings[$intervalKey][$pluralKey]),
                   $value);
    
    class creationTime extends DateTime {
    
        private $strings = array(
            'y' => array('1 year_ago', '%d years_ago'),
            'm' => array('1 month_ago', '%d months_ago'),
            'd' => array('1 day_ago', '%d days_ago'),
            'h' => array('1 hour_ago', '%d hours_ago'),
            'i' => array('1 minute_ago', '%d minutes_ago'),
            's' => array('just_now', '%d seconds_ago'),
        );
    
       private function getLocalized($string) {
    
            global $lang;
    
            $string == 'year_ago' ? $string = $lang['global.year_ago'] : null;
            $string == 'years_ago' ? $string = $lang['global.years_ago'] : null;
            $string == 'month_ago' ? $string = $lang['global.month_ago'] : null;
            $string == 'months_ago' ? $string = $lang['global.months_ago'] : null;
            $string == 'day_ago' ? $string = $lang['global.day_ago'] : null;
            $string == 'days_ago' ? $string = $lang['global.days_ago'] : null;
            $string == 'hour_ago' ? $string = $lang['global.hour_ago'] : null;
            $string == 'hours_ago' ? $string = $lang['global.hours_ago'] : null;
            $string == 'hour_ago' ? $string = $lang['global.hour_ago'] : null;
            $string == 'hours_ago' ? $string = $lang['global.hours_ago'] : null;
            $string == 'minute_ago' ? $string = $lang['global.minute_ago'] : null;
            $string == 'minutes_ago' ? $string = $lang['global.minutes_ago'] : null;
            $string == 'just_now' ? $string = $lang['global.just_now'] : null;
            $string == 'seconds_ago' ? $string = $lang['global.seconds_ago'] : null;
    
            return $string;
        }
    
        /**
         * Returns the difference from the current time in the format X time ago
         * @return string
         */
    
       public function __toString() {
            $now = new DateTime('now');
            $diff = $this->diff($now);
            foreach($this->strings as $key => $value){
                if( ($text = $this->getDiffText($key, $diff)) ){
                    return $text;
                }
            }
            return '';
        }
    
        /**
         * Try to construct the time diff text with the specified interval key
         * @param string $intervalKey A value of: [y,m,d,h,i,s]
         * @param DateInterval $diff
         * @return string|null
         */
        protected function getDiffText($intervalKey, $diff){
            $pluralKey = 1;
            $value = $diff->$intervalKey;
            if($value > 0){
                if($value < 2){
                    $pluralKey = 0;
                }
                $value = explode(' ', sprintf($this->strings[$intervalKey][$pluralKey], $value) );          
                return sprintf('%d %s', implode(array_slice($value, 0)), $this->getLocalized(implode(array_slice($value, 1))));
            }
            return null;
        }
    }
    
    class DateFormatter {
        private $localizer;
    
        private $strings = array(
            'y' => array('global.years_ago_1', 'global.years_ago_n'),
            'm' => array('global.months_ago_1', 'global.months_ago_n'),
            'd' => array('global.days_ago_1', 'global.days_ago_n'),
            'h' => array('global.hours_ago_1', 'global.hours_ago_n'),
            'i' => array('global.minutes_ago_1', 'global.minutes_ago_n'),
            's' => array('global.seconds_ago_1', 'global.seconds_ago_n'),
        );
    
        public function __construct(Localizer $localizer) {
            $this->localizer = $localizer;
        }
    
        /**
         * Returns the difference from the current time in the format X time ago
         * @return string
         */
        public function formatHowLongAgo(DateTime $date) {
            $now = new DateTime('now');
            $diff = $date->diff($now);
            foreach($this->strings as $unitOfTime => $formatStrings){
                $howMany = $diff->$unitOfTime;
                if (!$howMany) {
                    continue;
                }
    
                $plural = $howMany > 1;
                return $this->localizer->format($this->strings[$unitOfTime][$plural], $howMany);
            }
            return '??';
        }
    }
    
    // Packaged the localization stuff inside a class so that it's not
    // just hanging around in the global scope. Not much to see here,
    // a "real" localizer would have more features.
    class Localizer {
        private $lang = array(
            'global.years_ago_1'    => '1 year ago',
            'global.years_ago_n'    => '%d years ago',
            'global.months_ago_1'   => '1 month ago',
            'global.months_ago_n'   => '%d months ago',
            'global.days_ago_1'     => '1 day ago',
            'global.days_ago_n'     => '%d days ago',
            'global.hours_ago_1'    => '1 hour ago',
            'global.hours_ago_n'    => '%d hours ago',
            'global.minutes_ago_1'  => '1 minute ago',
            'global.minutes_ago_n'  => '%d minutes ago',
            'global.seconds_ago_1'  => 'just now',
            'global.seconds_ago_n'  => '%d seconds ago',
        );
    
        public function format($string /*, $param1, $param2, ... */) {
            $params = func_get_args(); // get variable # of params
            array_shift($params); // remove first item, we already have it in $string
            if (!isset($this->lang[$string])) {
                return '[['.$string.']]'; // a placeholder
            }
    
            return vsprintf($this->lang[$string], $params);
        }
    }
    
    $localizer = new Localizer;
    $timestamp = '1345284190';  // Example of Unix Timestamp
    $datetime = new DateTime("@$timestamp");
    $formatter = new DateFormatter($localizer);
    
    echo $formatter->formatHowLongAgo($datetime);