我应该如何去附加到所有将被发送为电子邮件的html字符串中的所有url的末尾?我想在谷歌分析跟踪活动添加到它是这样的:页面
?utm_source=email&utm_medium=email&utm_campaign=product_notify
如何附加到字符串中的所有网址?
99%不会“的.html”结束,某些URL可能会在他们结束已经有类似的东西?sr=1
。
我应该如何去附加到所有将被发送为电子邮件的html字符串中的所有url的末尾?我想在谷歌分析跟踪活动添加到它是这样的:页面
?utm_source=email&utm_medium=email&utm_campaign=product_notify
如何附加到字符串中的所有网址?
99%不会“的.html”结束,某些URL可能会在他们结束已经有类似的东西?sr=1
。
嗯...你可以做这样的事情:
function AppendCampaignToString($string) {
$regex = '#(<a href=")([^"]*)("[^>]*?>)#i';
return preg_replace_callback($regex, '_appendCampaignToString', $string);
}
function _AppendCampaignToString($match) {
$url = $match[2];
if (strpos($url, '?') === false) {
$url .= '?';
}
$url .= '&utm_source=email&utm_medium=email&utm_campaign=product_notify';
return $match[1].$url.$match[3];
}
这应该会自动查找网页上所有链接(即使是外部因素,所以要小心)。这个?检查只是确保我们附加一个查询字符串...
编辑:修正了在正则表达式没有按预期工作的问题。
您可以使用以下代码片段将您的Google Analytics分析GET参数附加到当前脚本URI的现有参数。
function getQuery() {
$url = parse_url($_SERVER['REQUEST_URI']);
return $url['query'].'&utm_source=email&utm_medium=email&utm_campaign=product_notify';
}
不错,但不是我要找的。我想追加到的URL是一串html。 – Echo 2010-06-07 14:59:55
<?php
$add = array(
'utm_source'=>'email',
'utm_medium'=>'email'
'utm_campaign'=>'product_notify');
$doc = new DOMDocument();
$doc->loadHTML('your html');
foreach($doc->getElementsByTagName('a') as $link){
$url = parse_url($link->getAttribute('href'));
$gets = isset($url['query']) ? array_merge(parse_str($url['query'])) : $add;
$newstring = '';
if(isset($url['scheme'])) $newstring .= $url['scheme'].'://';
if(isset($url['host'])) $newstring .= $url['host'];
if(isset($url['port'])) $newstring .= ':'.$url['port'];
if(isset($url['path'])) $newstring .= $url['path'];
$newstring .= '?'.http_build_query($gets);
if(isset($url['fragment'])) $newstring .= '#'.$url['fragment'];
$link->setAttribute('href',$newstring);
}
$html - $doc->saveHTML();
?>
太好了。这是处理事情的方式。没有完整的答案,但我正在寻找这样的事情。 – shamittomar 2014-04-08 08:07:24
我的解决方案我已经建立了&测试昨晚:
我只匹配这不已经有“utm_”之类的查询参数的链接,但包括以“utm_”链接作为部分路径:在查询另一个参数名称的参数或子字符串之前,比如“xutm_”。
为此,我已经使用正面和负面的正则表达式模式断言的组合(http://php.net/manual/en/regexp.reference.assertions.php)
我也允许标签之前有其他的属性和之后的href
$pattern = '/<a[^>]*href="(?=(.(?!(\?|&)utm_))*?>)[^"]*/i';
所有链接匹配它没有'utm_'也没有'& utm_'在href标记
然后,我使用类回调函数解决方案,以便能够传递查询参数被附加(作为额外参数RS回调)
class link_params{
private $parameters;
function __construct($params){
$this->parameters = $params;
}
function callback($matches){
return $matches[0] . (preg_match('/\\?[^"]/', $matches[0]) ? '&' : '?') . http_build_query($this->parameters);
}
}
准备,我要添加到链接查询参数:
$params_to_add = array(
'utm_source' => 'newsletter-sep13',
'utm_medium' => 'email',
'utm_campaign' => 'product-X'
);
$callback_helper = new link_params($params_to_add);
最后我申请的preg_replace_callback函数是这样的:
$html = preg_replace_callback($pattern, array($callback_helper, 'callback'), $html);
更新到@ ircmaxell的答案,即使在代码简化之前存在属性,正则表达式现在也可以匹配。
/**
* @param string $body
* @param string $campaign
* @param string $medium
* @return mixed
*/
protected function add_analytics_tracking_to_urls($body, $campaign, $medium = 'email') {
return preg_replace_callback('#(<a.*?href=")([^"]*)("[^>]*?>)#i', function($match) use ($campaign, $medium) {
$url = $match[2];
if (strpos($url, '?') === false) {
$url .= '?';
} else {
$url .= '&';
}
$url .= 'utm_source=' . $medium . '&utm_medium=' . $medium . '&utm_campaign=' . urlencode($campaign);
return $match[1] . $url . $match[3];
}, $body);
}
这里是我的解决方案,简单的问题,但相当复杂的解决方案与
$campaign = (object)['utm_source' => 'email', 'utm_medium' => 'email', 'utm_campaign' => 'abc'];
$host = 'www.me.com';
$html = preg_replace_callback(
'#(<a.*?href=["\']?)(?<href>https?://[^\s"\']+)(["\']?.*?>.*?</a>)#si', function ($matches) use ($campaign, $host) {
$url = parse_url($matches['href']);
// if (isset($url['host']) && $url['host'] !== $host) return $matches[0];
parse_str(isset($url['query']) ? $url['query'] : '', $query);
$query = array_merge(
$query, array_filter(
[
'utm_source' => $campaign->utm_source,
'utm_medium' => $campaign->utm_medium,
'utm_term' => $campaign->utm_term,
'utm_content' => $campaign->utm_content,
'utm_campaign' => $campaign->utm_campaign,
]
)
);
return $matches[1] . // anchor part before url
(isset($url['scheme']) ? $url['scheme'] . '://' : '') .
(isset($url['user']) ? $url['user'] : '') .
(isset($url['pass']) ? (isset($url['user']) ? ':' : '') . $url['pass'] : '') .
(isset($url['user']) || isset($url['pass']) ? '@' : '').
(isset($url['host']) ? $url['host'] : '') .
(isset($url['port']) ? ':' . $url['port'] : '') .
(isset($url['path']) ? $url['path'] : '') .
'?' . http_build_query($query) .
(isset($url['fragment']) ? '#' . $url['fragment'] : '') .
$matches[3]; // anchor part after URL
}, $html
);
最后一部分(CONCAT URL)所有的工作在URL类型也可以替换为http_build_url()
,但你将需要启用HTTP扩展。
<a href="http://www.me.com">Lorem</a>
<a href="http://www.me.com/">ipsum</a>
<a href="http://www.me.com/#section-2">dolor</a>
<a href="http://www.me.com/path-to-somewhere/file.php">sit</a>
<a href="http://www.me.com/?">amet</a>
<a href="http://www.me.com/?foo=bar">consectetur</a>
<a href="http://www.me.com/?foo=bar&bar=foo">consectetur</a>
<a href="http://www.NOTME.com?utm_source=XXX&utm_medium=XXX&utm_campaign=XXX">existing utm params</a>
<a href="http://user:[email protected]/?foo=bar#section-3">elit</a>
<a href="http://user:@www.me.com/?foo=bar#section-3">elit</a>
<a href="http://[email protected]?foo=bar#section-3">elit</a>
与结果如下:
<a href="http://www.me.com?utm_source=email&utm_medium=email&utm_campaign=abc">Lorem</a>
<a href="http://www.me.com/?utm_source=email&utm_medium=email&utm_campaign=abc">ipsum</a>
<a href="http://www.me.com/?utm_source=email&utm_medium=email&utm_campaign=abc#section-2">dolor</a>
<a href="http://www.me.com/path-to-somewhere/file.php?utm_source=email&utm_medium=email&utm_campaign=abc">sit</a>
<a href="http://www.me.com/?utm_source=email&utm_medium=email&utm_campaign=abc">amet</a>
<a href="http://www.me.com/?foo=bar&utm_source=email&utm_medium=email&utm_campaign=abc">consectetur</a>
<a href="http://www.me.com/?foo=bar&bar=foo&utm_source=email&utm_medium=email&utm_campaign=abc">consectetur</a>
<a href="http://www.NOTME.com?utm_source=email&utm_medium=email&utm_campaign=abc">existing utm params</a>
<a href="http://user:[email protected]/?foo=bar&utm_source=email&utm_medium=email&utm_campaign=abc#section-3">elit</a>
<a href="http://user:@www.me.com/?foo=bar&utm_source=email&utm_medium=email&utm_campaign=abc#section-3">elit</a>
<a href="http://[email protected]?foo=bar&utm_source=email&utm_medium=email&utm_campaign=abc#section-3">elit</a>
正如你可以看到,我的代码适用于在HTML中所有链接(不只是me.com)如果
代码是在跟踪的网址测试你想在parse_url()
之后过滤主机名取消注释行。
太棒了。谢谢。 – Echo 2010-06-07 15:03:34
嗯,应该在utm_source可能改写已经给了一个,被追加(PHP不能处理的$ _GET数组),或周围的其他方式? – Wrikken 2010-06-07 15:08:51
为我节省了很多时间,很棒的工作。 – jbnunn 2011-04-14 22:55:01