Neden bir "beklenmeyen regex" alabilirim

8 Cevap php

Amacınız mevcut çalışma dizini /clients/ de bölmek almak ve kullanıcı olup olmadığını görmek için

[something]/clients/[their username]/[something]

Örneğin, hedef giriş olacaktır:

cwd = "/volumes/raid0/www/clients/mikey/test_folder/"
$session->username = "mikey"

dönmek için

$authorized = true

Ben bu UNIX ve Windows yolları hem tanımak istiyorum, bu yüzden "/" veya "\" için bakmak gerekir. Bu dosya isimleri bu karakterleri içermez varsayılmıştır.

Ayrıca, isAdmin() bit yöneticileri tüm dizinlere erişim vermek gerekiyordu.

Şu anda, PHP diyor ki:

Warning: unexpected regex error (8) in c:\apache\htdocs\clients\mikey\index.php on line 69

Burada bu haliyle kod. (Line 69 yorum not edilir.)

if($session->isAdmin())
{
    $authorized = true;
} 
else 
{
  // split cwd at the first instance of /clients/
  $dir = spliti('%(\/|\\)clients(\/|\\)%',getcwd(),2); //this is line 69
  if(count($dir) == 2) // if /clients/ was in cwd
  {
    // check if the second piece of cwd starts with the username.
    $authorized = (preg_match('/^'.$session->username.'//*.$/', $dir[1]));
  } 
  else 
    $authorized = false;
}

8 Cevap

Burada normal ifadeler kullanmaya gerek yoktur, başka bir dizede bir dize arıyoruz. Yani böyle bir şey olur:

$isAuthorized = strpos(str_replace('\\', '/', getcwd()), "/clients/$username/") !== FALSE;

Bu no-karmaşık-regex varyantı olacaktır:

  • "/" de dize bölmek veya "\"
  • "clients" için elde edilen dizi aramak
  • bulursa bir sonraki pozisyonda eleman adı eşit olup olmadığını kontrol edin

PHP (denenmemiş olsa):

function isAuthorized($session)
{
  $authorized = $session->isAdmin();

  if(!$authorized)
  {
    $parts = split("[/\\\\]", $path);

    // find "clients", compare the following bit to the $session->username
    $clients_pos = array_search("clients", $parts);
    if ($clients_pos && count($parts) >= $clients_pos) 
      $authorized = ($parts[$clients_pos + 1] == $session->username);
    else
      $authorized = false;
  }
  return $authorized;
}

Böyle bir şey başlamak olabilir:

<?php
$regex = '%(.+)(/|\\\\)clients(/|\\\\)(.+)(/|\\\\)(.+)(/|\\\\)%';

preg_match($regex, "/volumes/raid0/www/clients/mikey/test_folder/", &$matches);
var_dump($matches);
?>

Çıkışlar:

 array(8) {
  [0]=>
  string(45) "/volumes/raid0/www/clients/mikey/test_folder/"
  [1]=>
  string(18) "/volumes/raid0/www"
  [2]=>
  string(1) "/"
  [3]=>
  string(1) "/"
  [4]=>
  string(5) "mikey"
  [5]=>
  string(1) "/"
  [6]=>
  string(11) "test_folder"
  [7]=>
  string(1) "/"
}

Eğer çok daha kısa kod parçası yazmak için izin vermelidir. Eğer kaçış çift var unutmayın. Bu çirkin, ben biliyorum.

Lütfen regex çok yolları tersbölülerle hesaba çalışıyor? Muhtemelen gerekli değil. Sonra ayırabilirsiniz:

'%/clients/%'

(Eğer regex sınırlayıcı olarak kullanabilirsiniz% beri düzenli çizgi kaçmak gerekmez.)

Bu kod sınanmış, standart feragatnameler geçerli:

if($session->isAdmin()) {
   $authorized = true;
} else {
   // split cwd at the first instance of /clients/
   $dir = preg_split('/(\/|\\)clients(\\|\/)/i', getcwd());
   if(count($dir) == 2) { // if /clients/ was in cwd
      // check if the second piece of cwd starts with the username.
      $dir = preg_split('/\/|\\/', $dir[1]);
      $authorized = ($dir[0] == $session->username);
   } else {
      $authorized = false;
   }
}

Bu benim PHP uyarısı düzeltildi:

if($session->isAdmin())
{
    $authorized = true;
} else {
    // split cwd at the first instance of /clients/
    $dir = spliti('%(/|\\\\)clients(/|\\\\)%',getcwd(),2);
    if(count($dir) == 2) // if /clients/ was in cwd
    	{
    		// check if the second piece of cwd starts with the username.
    		$authorized = (preg_match('%^'.$session->username.'*(/|\\\\)*.$%', $dir[1]));
    } else $authorized = false;
}

Sorun spliti () Benim cwd () dönüş bölme değil, ... Ben ile test ediyorum cwd () dönüş:

c: \ apache \ htdocs \ istemcileri Mikey \

Ben de "/" veya "\" kullanmak mümkün olmak istiyorum beni regex kullanmak güçlerin hangi tür (benim bilgi için.)

Ruben çözümü (buna izin dizin derinliğini sınırlamak gibi görünüyor) ama ben bu anlamaya olamaz eğer işe yarayabilecek daha zariftir.

Ben çekiçle tutmak ve ben neler çözemeyeceğinizi görmek için gidiyorum (hepsi benim spliti bir sorun (bu noktada) regex gibi görünüyor.)

giriş / geribildirim her zaman soruna tam bir çözüm olmasa bile, takdir (ya da ilgili. benim kod berbat varsa bana bildirin.)

thanks! --Will (OP)

OKAY, bu çözüldü. Ben preg_split ile split () () yerine ihtiyaç ...

I DIRECTORY_SEPARATOR is currently used and then do a simple strpos üzerinde kontrol ne kontrol ediyorum:

$cwd = getcwd();
if (DIRECTORY_SEPARATOR != '/') {
    $cwd = str_replace(DIRECTORY_SEPARATOR, '/', $cwd);
}
$authorized = (strpos($cwd, '/clients/'.$session->username.'/') !== false);