将内容放在没有图像的段落之间

时间:2014-02-28 09:53:03

标签: php html

我使用以下代码在我的内容中放置一些广告代码。

<?php
$content = apply_filters('the_content', $post->post_content);
$content = explode (' ', $content);
$halfway_mark = ceil(count($content) / 2);
$first_half_content = implode(' ', array_slice($content, 0, $halfway_mark));
$second_half_content = implode(' ', array_slice($content, $halfway_mark));
echo $first_half_content.'...';
echo ' YOUR ADS CODE';
echo $second_half_content;
?>

如何修改此内容,以便包含广告代码的2个段落(顶部和底部)不应该是包含图片的段落。如果顶部或底部段落有图像,请尝试下一个2段落。

示例:在右侧正确实施。

enter image description here

4 个答案:

答案 0 :(得分:3)

preg_replace版本

此代码逐步执行每个段落,忽略包含图像标记的段落。对于没有图像的每个段落,$pcount变量会递增,但如果遇到图像,$pcount将重置为零。一旦$pcount到达它将达到2的点,就会在该段落之前插入广告标记。这应该在两个安全段落之间留下广告标记。然后广告标记变量无效,因此只插入一个广告。

以下代码仅用于设置,可以修改为以不同方式拆分内容,您也可以修改使用的正则表达式 - 以防您使用双BR或其他东西来分隔段落。

/// set our advert content
$advert = '<marquee>BUY THIS STUFF!!</marquee>' . "\n\n";
/// calculate mid point
$mpoint = floor(strlen($content) / 2);
/// modify back to the start of a paragraph
$mpoint = strripos($content, '<p', -$mpoint);
/// split html so we only work on second half
$first  = substr($content, 0, $mpoint);
$second = substr($content, $mpoint);
$pcount = 0;
$regexp = '/<p>.+?<\/p>/si';

其余的是运行替换的大部分代码。可以修改此选项以插入多个广告,或支持更多涉及的图像检查。

$content = $first . preg_replace_callback($regexp, function($matches){
  global $pcount, $advert;
  if ( !$advert ) {
    $return = $matches[0];
  }
  else if ( stripos($matches[0], '<img ') !== FALSE ) {
    $return = $matches[0];
    $pcount = 0;
  }
  else if ( $pcount === 1 ) {
    $return = $advert . $matches[0];
    $advert = '';
  }
  else {
    $return = $matches[0];
    $pcount++;
  }
  return $return;
}, $second);

执行此代码后,$content变量将包含增强的HTML。


5.3之前的PHP版本

由于您选择的测试区域不支持PHP 5.3,因此不支持匿名功能,您需要使用略微修改且不太简洁的版本;而是使用命名函数。

此外,为了支持可能实际上没有为广告留出空间的内容,我已经修改了$mpoint,以便计算结果为80%。这将在$second部分中包含更多内容 - 但也意味着您的广告通常会在加价中位居前列。此代码没有实现任何后备,因为您的问题没有提到在发生故障时应该发生什么。

$advert = '<marquee>BUY THIS STUFF!!</marquee>' . "\n\n";
$mpoint = floor(strlen($content) * 0.8);
$mpoint = strripos($content, '<p', -$mpoint);
$first  = substr($content, 0, $mpoint);
$second = substr($content, $mpoint);
$pcount = 0;
$regexp = '/<p>.+?<\/p>/si';

function replacement_callback($matches){
  global $pcount, $advert;
  if ( !$advert ) {
    $return = $matches[0];
  }
  else if ( stripos($matches[0], '<img ') !== FALSE ) {
    $return = $matches[0];
    $pcount = 0;
  }
  else if ( $pcount === 1 ) {
    $return = $advert . $matches[0];
    $advert = '';
  }
  else {
    $return = $matches[0];
    $pcount++;
  }
  return $return;
}

echo $first . preg_replace_callback($regexp, 'replacement_callback', $second);

答案 1 :(得分:1)

你可以试试这个:

    <?php
  $ad_code = 'SOME SCRIPT HERE';

  // Your code.
  $content = apply_filters('the_content', $post->post_content);

  // Split the content at the <p> tags.
  $content = explode ('<p>', $content);

  // Find the mid of the article.
  $content_length = count($content);
  $content_mid = floor($content_length / 2);

  // Save no image p's index.
  $last_no_image_p_index = NULL;

  // Loop beginning from the mid of the article to search for images.
  for ($i = $content_mid; $i < $content_length; $i++) {
    // If we do not find an image, let it go down.
    if (stripos($content[$i], '<img') === FALSE) {
      // In case we already have a last no image p, we check 
      // if it was the one right before this one, so we have
      // two p tags with no images in there.
      if ($last_no_image_p_index === ($i - 1)) {
        // We break here.
        break;
      }
      else {
        $last_no_image_p_index = $i;
      }
    }
  }

  // If no none image p tag was found, we use the last one.
  if (is_null($last_no_image_p_index)) {
    $last_no_image_p_index = ($content_length - 1);
  }

  // Add ad code here with trailing <p>, so the implode later will work correctly.
  $content = array_slice($content, $last_no_image_p_index, 0, $ad_code . '</p>');

  $content = implode('<p>', $content);
?>

它会尝试从文章中间找到广告的位置,如果找不到广告,广告就会被放到最后。

此致 func0der

答案 2 :(得分:0)

我认为这会奏效:

首先爆炸段落,然后你必须循环它并检查你是否在其中找到了img。 如果你在里面找到它,你可以尝试下一个。

将其视为伪代码,因为它未经过测试。你也必须做一个循环,代码中的注释:)抱歉,如果它包含错误,它是用记事本写的。

<?php
$i = 0; // counter
$arrBoolImg = array(); // array for the paragraph booleans

$content = apply_filters('the_content', $post->post_content);

$contents = str_replace ('<p>', '<explode><p>', $content); // here we add a custom tag, so we can explode
$contents = explode ('<explode>', $contents); // then explode it, so we can iterate the paragraphs

// fill array with boolean array returned
$arrBoolImg = hasImages($contents);
$halfway_mark = ceil(count($contents) / 2);

/* 
    TODO (by you):
    ---
    When you have $arrBoolImg filled, you can itarate through it.
    You then simply loop from the middle of the array $contents (plural), that is exploded from above.
    The startingpoing for your loop is the middle, the upper bounds is the +2 or what ever :-)
    Then you simply insert your magic.. And then glue it back together, as you did before.
    I think this will work. even though the code may have some bugs, since I wrote it in Notepad.
*/






function hasImages($contents) {
/* 
This function loops through the $contents array and checks if they have images in them
The return value, is an array with boolean values, so one can iterate through it.
*/
$arrRet = array(); // array for the paragraph booleans

if (count($content)>=1) {
    foreach ($contents as $v) { // iterate the content
    if (strpos($v, '<img') === false) { // did not find img
        $arrRet[$i] = false;
        }
        else {              // found img
        $arrRet[$i] = true; 
    }
    $i++;
    } // end for each loop
    return $arrRet;
} // end if count
} // end hasImages func

?>

答案 3 :(得分:0)

[这只是一个想法,我没有足够的声誉来发表评论......]

在调用@Olavxxx的方法并填充你的布尔数组之后,你可以从中间开始以交替的方式遍历该数组:假设你的数组是8个条目长。使用你得到的方法计算中间值4.所以你检查值4 + 3的组合,如果不起作用,你检查4 + 5,在3 + 2之后,......

所以你的循环看起来有点像

$middle = ceil(count($content) / 2);
$i = 1;
while ($i <= $middle) {
  $j = $middle + (-1) ^ $i * $i;
  $k = $j + 1;

  if (!$hasImagesArray[$j] && !$hasImagesArray[$k])
    break; // position found

  $i++;
}

由您来实施进一步的约束,以确保在文章中没有向上或向下显示添加...

请注意,您需要处理特殊情况,例如太短的数组,以防止IndexOutOfBounds-Exceptions。