将target _blank添加到外部链接-解析PHP
我正在使用解析HTML从数据库到我的网站。使用Parsedown,您无法真正将将target _blank添加到外部链接-解析PHP,php,parsing,Php,Parsing,我正在使用解析HTML从数据库到我的网站。使用Parsedown,您无法真正将target=“\u blank”添加到链接中 所以我想做的是将target=“\u blank”添加到外部链接。我在Parsedown.php中找到了这个函数: protected function inlineLink($Excerpt) { $Element = array( 'name' => 'a', 'handler' => 'line',
target=“\u blank”
添加到链接中
所以我想做的是将target=“\u blank”
添加到外部链接。我在Parsedown.php中找到了这个函数:
protected function inlineLink($Excerpt)
{
$Element = array(
'name' => 'a',
'handler' => 'line',
'text' => null,
'attributes' => array(
'href' => null,
'title' => null,
),
);
$extent = 0;
$remainder = $Excerpt['text'];
if (preg_match('/\[((?:[^][]++|(?R))*+)\]/', $remainder, $matches))
{
$Element['text'] = $matches[1];
$extent += strlen($matches[0]);
$remainder = substr($remainder, $extent);
}
else
{
return;
}
if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*"|\'[^\']*\'))?\s*[)]/', $remainder, $matches))
{
$Element['attributes']['href'] = $matches[1];
if (isset($matches[2]))
{
$Element['attributes']['title'] = substr($matches[2], 1, - 1);
}
$extent += strlen($matches[0]);
}
else
{
if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
{
$definition = strlen($matches[1]) ? $matches[1] : $Element['text'];
$definition = strtolower($definition);
$extent += strlen($matches[0]);
}
else
{
$definition = strtolower($Element['text']);
}
if ( ! isset($this->DefinitionData['Reference'][$definition]))
{
return;
}
$Definition = $this->DefinitionData['Reference'][$definition];
$Element['attributes']['href'] = $Definition['url'];
$Element['attributes']['title'] = $Definition['title'];
}
$Element['attributes']['href'] = str_replace(array('&', '<'), array('&', '<'), $Element['attributes']['href']);
return array(
'extent' => $extent,
'element' => $Element,
);
}
inlineLink中受保护的函数($节选)
{
$Element=数组(
'name'=>'a',
'处理程序'=>'行',
'text'=>null,
'属性'=>数组(
'href'=>null,
'title'=>null,
),
);
$extent=0;
$rements=$extract['text'];
if(preg_match('/\[((?:[^][+++;(?R))*+)\]/',$rements,$matches))
{
$Element['text']=$matches[1];
$extent+=strlen($matches[0]);
$rements=substr($rements,$extent);
}
其他的
{
返回;
}
如果(预匹配('/^[(]\s*+((?:[^()]+++.[(][^)]+[)])+(?:[]+(“[^”]*“\\'[^\']*'))?\s*[)]/',$restins,$matches))
{
$Element['attributes']['href']=$matches[1];
如果(isset($matches[2]))
{
$Element['attributes']['title']=substr($matches[2],1,-1);
}
$extent+=strlen($matches[0]);
}
其他的
{
if(preg_match('/^\s*\[(.*?\]/',$restinutes,$matches))
{
$definition=strlen($matches[1])?$matches[1]:$Element['text'];
$definition=strtolower($definition);
$extent+=strlen($matches[0]);
}
其他的
{
$definition=strtolower($Element['text']);
}
如果(!isset($this->DefinitionData['Reference'][$definition]))
{
返回;
}
$Definition=$this->DefinitionData['Reference'][$Definition];
$Element['attributes']['href']=$Definition['url'];
$Element['attributes']['title']=$Definition['title'];
}
$Element['attributes']['href']=str_replace(数组('&','a',),
'处理程序'=>'行',
'text'=>null,
'属性'=>数组(
'href'=>null,
'target'=>null,//添加了这个
'title'=>null,
),
);
$extent=0;
$rements=$extract['text'];
if(preg_match('/\[((?:[^][+++;(?R))*+)\]/',$rements,$matches))
{
$Element['text']=$matches[1];
$extent+=strlen($matches[0]);
$rements=substr($rements,$extent);
}
其他的
{
返回;
}
如果(预匹配('/^[(]\s*+((?:[^()]+++.[(][^)]+[)])+(?:[]+(“[^”]*“\\'[^\']*'))?\s*[)]/',$restins,$matches))
{
$Element['attributes']['href']=$matches[1];
如果(isset($matches[2]))
{
$Element['attributes']['title']=substr($matches[2],1,-1);
}
$extent+=strlen($matches[0]);
}
其他的
{
if(preg_match('/^\s*\[(.*?\]/',$restinutes,$matches))
{
$definition=strlen($matches[1])?$matches[1]:$Element['text'];
$definition=strtolower($definition);
$extent+=strlen($matches[0]);
}
其他的
{
$definition=strtolower($Element['text']);
}
如果(!isset($this->DefinitionData['Reference'][$definition]))
{
返回;
}
$Definition=$this->DefinitionData['Reference'][$Definition];
$Element['attributes']['href']=$Definition['url'];
if(strpos($Definition['url'],'example.com')!==false){//也添加了这个,检查它是否是我们自己的url
$Element['attributes']['target']='u blank';
}
$Element['attributes']['title']=$Definition['title'];
}
$Element['attributes']['href']=str_replace(数组('&','在GitHub上出现此类问题。请参阅评论
我的扩展可以自动设置rel=“nofollow”和target=“\u blank”
当链接被检测为外部链接时,它的属性。您可以
还可以通过属性块手动设置这些属性:
[text](http://example.com) {rel="nofollow" target="_blank"}
如果要在Parsedown类中进行更改而不使用Parsedown额外插件扩展,可以执行以下操作:
1) 在
\Parsedown::element
方法中,$markup='今天遇到了这个问题。我想让来自不同主机的所有链接自动在新目标中打开。不幸的是,接受的答案建议编辑Parsedown类文件,这在我看来是个坏主意
我创建了一个新的PHP类,它扩展了Parsedown
,并为元素
方法创建了一个重写。下面是整个类:
class ParsedownExtended extends Parsedown
{
protected function element(array $Element)
{
if ($this->safeMode) {
$Element = $this->sanitiseElement($Element);
}
$markup = '<' . $Element['name'];
if (isset($Element['name']) && $Element['name'] == 'a') {
$server_host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : null;
$href_host = isset($Element['attributes']['href']) ? parse_url($Element['attributes']['href'], PHP_URL_HOST) : null;
if ($server_host != $href_host) {
$Element['attributes']['target'] = '_blank';
}
}
if (isset($Element['attributes'])) {
foreach ($Element['attributes'] as $name => $value) {
if ($value === null) {
continue;
}
$markup .= ' ' . $name . '="' . self::escape($value) . '"';
}
}
if (isset($Element['text'])) {
$markup .= '>';
if (!isset($Element['nonNestables'])) {
$Element['nonNestables'] = array();
}
if (isset($Element['handler'])) {
$markup .= $this->{$Element['handler']}($Element['text'], $Element['nonNestables']);
}
else {
$markup .= self::escape($Element['text'], true);
}
$markup .= '</' . $Element['name'] . '>';
}
else {
$markup .= ' />';
}
return $markup;
}
}
现在我只需在解析内容时使用ParsedownExtended
而不是Parsedown
,例如:
$parsedown = new ParsedownExtended();
return $parsedown->text($this->body);
希望这对其他人有所帮助。就像kjdion84一样,我也会扩展解析类。我建议不要复制和更改元素
方法,而是覆盖inlineLink
;如果基础代码发生更改,工作会更少,而且更能证明未来
注意:urlIsExternal
方法绝对不完整(缺少主机检查)
类ParsedownExtended扩展了Parsedown
{
inlineLink中受保护的函数($摘录)
{
$link=parent::inlineLink($摘录);
if($this->urlIsExternal($link['element']['attributes']['href'])){
$link['element']['attributes']+=[
'目标'=>'\u空白',
'rel'=>'nofollow',
];
}
返回$link;
}
受保护函数urlIsExternal($url)
{
$scheme=parse_url($url,PHP_url_scheme);
$host=parse_url($url,PHP_url_host);
if(!$scheme | |!$host){
返回false;
}
if(strpos(strtolower($scheme),'http')!=0){
返回false;
}
//@TODO检查主机
返回true;
}
}
我已经尝试了Parsedown Extra,但是插件没有满足我的需求,我很抱歉
protected function additionalProcessElement($Element) { }
<?php
namespace myapps;
require_once __DIR__.'/Parsedown.php';
/**
* Class MyParsedown
* @package app
*/
class MyParsedown extends \Parsedown
{
/**
* @param array $Element
* @return array
*/
protected function additionalProcessElement($Element)
{
if ($Element['name'] == 'a' && $this->isExternalUrl($Element['attributes']['href'])) {
$Element['attributes']['target'] = '_blank';
}
return $Element;
}
/**
* Modification of the funciton from answer to the question "How To Check Whether A URL Is External URL or Internal URL With PHP?"
* @param string $url
* @param null $internalHostName
* @see https://stackoverflow.com/a/22964930/7663972
* @return bool
*/
protected function isExternalUrl($url, $internalHostName = null) {
$components = parse_url($url);
$internalHostName = ($internalHostName == null) ? $_SERVER['HTTP_HOST'] : $internalHostName;
// we will treat url like '/relative.php' as relative
if (empty($components['host'])) {
return false;
}
// url host looks exactly like the local host
if (strcasecmp($components['host'], $internalHostName) === 0) {
return false;
}
$isNotSubdomain = strrpos(strtolower($components['host']), '.'.$internalHostName) !== strlen($components['host']) - strlen('.'.$internalHostName);
return $isNotSubdomain;
}
}
require_once __DIR__.'/MyParsedown.php';
$parsedown = new \myapps\MyParsedown();
$text = 'External link to [example.com](http://example.com/abc)';
echo $parsedown->text($text);
class ParsedownExtended extends Parsedown
{
protected function element(array $Element)
{
if ($this->safeMode) {
$Element = $this->sanitiseElement($Element);
}
$markup = '<' . $Element['name'];
if (isset($Element['name']) && $Element['name'] == 'a') {
$server_host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : null;
$href_host = isset($Element['attributes']['href']) ? parse_url($Element['attributes']['href'], PHP_URL_HOST) : null;
if ($server_host != $href_host) {
$Element['attributes']['target'] = '_blank';
}
}
if (isset($Element['attributes'])) {
foreach ($Element['attributes'] as $name => $value) {
if ($value === null) {
continue;
}
$markup .= ' ' . $name . '="' . self::escape($value) . '"';
}
}
if (isset($Element['text'])) {
$markup .= '>';
if (!isset($Element['nonNestables'])) {
$Element['nonNestables'] = array();
}
if (isset($Element['handler'])) {
$markup .= $this->{$Element['handler']}($Element['text'], $Element['nonNestables']);
}
else {
$markup .= self::escape($Element['text'], true);
}
$markup .= '</' . $Element['name'] . '>';
}
else {
$markup .= ' />';
}
return $markup;
}
}
if (isset($Element['name']) && $Element['name'] == 'a') {
$server_host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : null;
$href_host = isset($Element['attributes']['href']) ? parse_url($Element['attributes']['href'], PHP_URL_HOST) : null;
if ($server_host != $href_host) {
$Element['attributes']['target'] = '_blank';
}
}
$parsedown = new ParsedownExtended();
return $parsedown->text($this->body);