【问题标题】:wrapping href around implode variable将 href 包裹在 implode 变量周围
【发布时间】:2012-10-12 23:49:54
【问题描述】:

我有一个 php 内爆函数来列出 wordpress 自定义字段键,效果很好。问题是我需要将 web url 包装在 href 中以使它们可点击,并且无法将我的头包裹在函数 sytnax.xml 中。键值的格式为 www.site.com,因此我将其设置为单个条目,如下所示:

<?php if(get_post_meta($post->ID, 'website', true)): ?>
    <strong>Website:</strong> <a href="http://<?php echo get_post_meta($post->ID, 'website', true); ?>" target="_blank"><?php echo get_post_meta($post->ID, 'website', true); ?></a>
<?php endif; ?>

但现在我们需要能够保存多个用逗号分隔的条目。这是有效的代码,但不输出可点击的网址:

<?php
if( $website = get_post_meta($post->ID, 'website') ):
    $label = count( $website ) > 1 ? 'Websites' : 'Website';
    ?>
    <strong><?php echo $label; ?>:</strong> <?php echo implode( $website, ', ' ); ?><br />
    <?php
endif;
?>

这是我一直在玩的,这显然是错误的

<?php echo '<a href="http://' . implode('" target="_blank">', $website) . "</a>" . ', '; ?><br />

即使它确实工作了,它也只会输出 url,而不是链接的文本。

---------- 编辑 -------------

Kai 的答案最接近,所以我将其标记为答案,但它不包含 label 变量。通过与他们中的两个结婚,我想出了这个很好用的答案

<?php
    if( $website = get_post_meta($post->ID, 'website') ):
        $label = count( $website ) > 1 ? 'Websites' : 'Website';
        $links = array_map(
            function($url) {
                 $url = htmlspecialchars($url);
                 return sprintf ('<a href="http://%s">%s</a>', $url, $url);
            },
            $website);
        ?>
        <strong><?php echo $label; ?>:</strong> <?php echo implode(', ', $links); ?><br />
<?php endif ?>

【问题讨论】:

    标签: php syntax implode


    【解决方案1】:
    <?php
    if( $website = get_post_meta($post->ID, 'website') ):
        $label = count( $website ) > 1 ? 'Websites' : 'Website';
        ?>
        <strong><?php echo $label; ?>:</strong> 
        <?php foreach($website AS $w): ?>
            <a href="<?php echo $w; ?>" target="_blank"><?php echo $w; ?></a> <br />
        <?php endforeach; ?>      
    <?php endif; ?>
    

    这假设您的数组中的每个“网站”都是一个完整的有效 url,包括 http://

    我认为问题的根源在于了解 implode 的作用以及为什么它不能按您想要的方式工作。

    编辑:

    我明白了,您希望它们位于以逗号分隔的内联列表中。你应该使用 Jon 的方法,因为它会比我在这里建议的更优雅地做你想做的事。

    【讨论】:

    • 这会返回值,但不考虑逗号...如果我在函数中添加逗号,它会将其添加到每个 url,包括最后一个。你不理解内爆是对的。我在学习!
    【解决方案2】:

    您可以以类似于您自己尝试过的方式严重滥用implode 并使其发挥作用,但这确实不是一个好主意。

    您想要的是从 URL 列表移动到锚标记列表,这可以通过 array_map 实现:

    if ($website = get_post_meta($post->ID, 'website')) {
        $links = array_map(
            function($url) {
                 $url = htmlspecialchars($url);
                 return sprintf ('<a href="http://%s">%s</a>', $url, $url);
            },
            $website);
    
        echo implode(', ', $links);
    }
    

    【讨论】:

    • 我在一个代码编辑器中,所以它不会“说”任何东西,它只是在它旁边有一个警告颜色,并且它下面的代码的所有颜色都会改变。我尝试在最后一个大括号中添加一个分号,但它也不喜欢这样。您介意编辑它以包含&lt;?php 位吗?也许我只是个笨蛋,没有正确实施?
    • 我遇到的问题是在此之后有一个&lt;?php endif; ?&gt;,显然不需要。这个解决方案很棒,但是它忽略了标签Website:
    • 这是最接近的,因此我将其标记为答案,但是由于它不包含标签变量,因此我编辑了原始问题以包含最终解决方案。
    【解决方案3】:

    您需要使用装饰器模式。修改下面的示例以满足您的需求

    interface HtmlElementInterface {
        public function getText();
        public function render();
    }
    
    class LinkDecorator implements HtmlElementInterface {
    
        protected $title;
        protected $text;
    
        public function __construct($text, $title, $renderNow = false) {
            if (!is_string($text) || empty($text)) {
                throw new InvalidArgumentException("The text of the element must be a non-empty string.");
            }
            $this->text = $text;
            $this->title = $title;
            if ($renderNow) {
                echo $this->render();
            }
        }
    
        public function getText() {
            return $this->text;
        }
    
        public function render() {
            // do your magic here
            return "<a href='" . $this->text . "'>" . $this->title . "</a>";
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2015-05-09
      • 2016-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多