Cümle İçerisinde Arama
// filtre.json
{
"kelimeler":[
"******",
"s....",
"g....",
"a...."
]
}
Class Filtre {
public $dosya = "filtre.json";
public function Filtre($Filtre){
$File = file_get_contents($this->dosya);
$File = json_decode($File);
$File = $File->kelimeler;
$response = [];
foreach ($File as $key => $value) {
$response[] = [$value];
}
$Result = json_encode($response);
$String = strstr($Result, $Filtre);
if($String === false):
return false;
else:
return true;
endif;
}
}
arkadaşlar böyle birşey yaptım fakat istediğim gibi çalışmıyor.
cümle içerisinde
$kelime = "Uzaylı seni yakalarsam ****** içinden geçerim";
$Filtre = new Filtre();
print_r($Filtre->Filtre($kelime));
sonuç false dönüyor true dönmesi lazım fakat
$kelime = "******";
$Filtre = new Filtre();
print_r($Filtre->Filtre($kelime));
cümle içerisinde tam bir arama yapmak istiyorum yardımcı olurmusunuz bununla ilgili.
Üzerinde epeyi uğraştım, son hâlini alana kadar türlü revizyondan geçti. Ama yine de yüzde yüz engellemeyebilir. Aklıma geldiği kadarını eklemeye çalıştım.
class Filter
{
protected $dosya;
const STARS = '*****';
public function __construct()
{
$this->dosya = json_decode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'filtre.json'), true)['kelimeler'];
}
private function explode($words)
{
$list = ['.',',',':',';','!','?','=','-','_','/','\\','%','&','(',')','{','}','[',']','\'','"','*','+','^','#','$','@','₺','€'];
$words = trim(str_replace($list, ' ', $words));
preg_match_all('/(\b\S+\b)/u', $words, $matches);
$recursive = function ($arg, $k, $v) use (&$recursive) {
static $arr;
$newArr = array_chunk($arg, $k);
$newStr = mb_strtolower(implode(' ', $newArr[0]));
$arr[$newStr] = in_array($newStr, $v);
array_shift($arg);
if (count($arg) && count($arg) >= $k) {
$recursive($arg, $k, $v, $arr);
}
return $arr;
};
$results = [];
if (count($this->dosya)) {
foreach ($this->dosya as $k => $v) {
$results = $recursive($matches[0], $k, $v);
}
}
return $results;
}
/**
* @param $username
* @return void
* - Bu metod usernameFilter metodunun test hâlidir, yasaklı kelime ile eşleştiğinde echo ile yazdırabilmek için kullan, asıl çalışan metod üstteki, testten sonra bu metodu silebilirsin
*/
public function usernameFilterForTest($username)
{
$results = $this->explode($username);
if (count($results)) {
foreach ($results as $k => $v) {
if ($v) {
echo "Yasaklı kelime bulundu. Eşleşen kelime <b>$k</b><br>";
// Kullanıcı adı yasaklı kelimeler listesinde bir şekilde var
// Kullanıcı adı bir kelime veya bir kelimeden fazla ise bile eşleşme sağlanıyor. 3 kelimeli bir ad olsa ve son iki kelimesi, yasaklı kelimeler listesinin 2 kelimelik listesinde varsa bile eşleşme sağlanır
}
}
}
}
/**
* @param $comment
* @param bool $one2oneFilter - Yorum içerisinde bulunan yasaklı kelimelerin kendi harf sayılarına göre filtrelenme seçeneği. Örneğin yasaklıKelime kelimesi bulunduğunda bu değer true ise kendi harf sayısı kadar * koyulur *************; false ise alttaki STARS sabitindek, kadar yıldız koyulur
* @param bool $forceFilter - Bu da aslında sizin 'komple bir metnin içeriğinde kelime avına çıkma' isteğiniz için bir seçenek. true verilirse yasaklı bir kelime başka bir kelimenin içinde bulunsa bile filtrelenir. false ise sadece tam olarak bir kelime şeklinde yasaklı listesinde varsa filtrelenir
* @return array|string|string[]|null
*/
public function commentFilter($comment, bool $one2oneFilter = true, bool $forceFilter = false)
{
$results = $this->explode($comment);
$filter = array_filter($results, function ($item) {
return $item;
});
$h = array_map(function ($item) use ($forceFilter) {
if ($forceFilter)
return "/$item/i";
else
return "/\b$item\b/i";
}, array_keys($filter));
if ($one2oneFilter) { // Eğer * işaretlerini filtrelenen kelimenin tam harfleri ile uyumlu şekilde koymak istiyorsak
$replacemenet = [];
for ($i = 0; $i < count($h); $i++) {
$str = '';
if ($forceFilter)
$a = substr($h[$i],1, -2);
else
$a = substr($h[$i],3, -4);
$p = explode(' ', $a);
foreach ($p as $item) {
$str .= str_repeat('*', mb_strlen($item)) . ' ';
}
$replacemenet[] = $str;
}
$response = preg_replace($h, $replacemenet, $comment);
}
else
$response = preg_replace($h, self::STARS, $comment);
return $response;
}
/**
* @param $username
* @return bool
* - Kullanıcı adında yasaklı kelimeler varsa false yoksa true döndürür
*/
public function usernameFilter($username): bool
{
$username = trim($username);
preg_match_all('/\pL+/u', $username, $matches);
$results = $this->explode($matches[0]);
if (count($results)) {
foreach ($results as $v) {
if ($v)
return false;
}
}
return true;
}
}
// Bir defa oluşturduktan sonra aşağıdaki kısmı silebilirsin
###################################
// Örnek bir yasaklı kelimeler json dosyası oluşumu. Yasaklı kelimeleri içerdikleri kelime sayılarına göre gruplandırdım. Yazdığım sınıfta buna göre bütün yasaklı kelimeleri verilen yorum veya kullanıcı adındaki kelimeleri bu listede bulunan harf sayılarına göre teker teker bölüp arıyor.
$kelimeler = [
'kelimeler' => [
1 => [
'kaybol',
'yasaklıKelime',
'sarkozy',
'sak1z',
'yani',
],
2 => [
'tuvalet terliği',
'naylon poşet',
'yasaklı kelime'
],
3 => [
'yasaklı bir kelime',
'üç kelime yasaklı',
'elli birinci bölge'
],
4 => [
'zincirleme k1üfür içeren kelimeler'
]
]
];
file_put_contents('filtre.json', json_encode($kelimeler, JSON_UNESCAPED_UNICODE));
###################################
// Biraz gereksiz kod tekrarı olmuş olabilir, olabildiğince kkısa yollarla halletmeye çalıştıkça türlü sıkıntılar çıktı. Çook uzun yorumlarda belki ufak bir gecikme sorunu yaşanabilir emin değilim. Çünkü yorumu çok fazla parçaya ayırıp kontrol etmeye çalışacak. Umarım işinize yarar.
$username = 'yasaklı kelime içeren kullanıcı adı';
$filter = new Filter();
//$filter->usernameFilterForTest($username);
/******* if ($filter->usernameFilter($username)) {
// Sonuç başarılı, yasaklı kelime çıkmamış, bu kullanıcı adıyla kayıt olabilir
echo 'başarılı';
}
else {
// Sonuç başarısız, kullanıcı adının içinde bir şekilde yasaklı kleime tespit edildi, bu kullanıcı adıyla kayıt olamaz
echo 'Başarısız';
}*******/ // Orijinal kullanıcı adı kontrolü
$comment = 'Bu yorumun içerisinde yasaklı kelimeler bulunabilir. İçinde sayı olan yasaklı kelimeler de olabilir, mesela sak1z gibi. Örneğin sarkozy kelimesi yasaklı bir kelimedir ve filtrelenecektir. Aynı şekilde naylon poşet de yasaklı kelime listesinde mevcuttur.Zincirleme k1üfür içeren kelimeler de filtrelenir :) Yani kelimesi tek başına filtrelenir ama malayani veya süryanice gibi içerisinde bulunuyorsa filtrelenmeyebilir.';
$filteredeComment = $filter->commentFilter($comment);
echo "<b>Sadece tam eşleşmeler filtrelenmiş hâli</b>: $filteredeComment";
echo '<br><br>';
$filteredeComment = $filter->commentFilter($comment, forceFilter: true); // PHP 8 sözdimizi. Eğer PHP 8 değilse senin sürüm alttki yorum satırındakini kullan
//$filteredeComment = $filter->commentFilter($comment, true, true);
echo "<b>Bütün eşleşmelerin filtrelenmiş hâli</b>: $filteredeComment";
echo '<br><br>';
echo "<b>Orijinal metin</b>: $comment";