PHP'de bir dizini [yinelemeli olarak] Zip nasıl sıkıştırılır?


118

Dizin şuna benzer:

home/
    file1.html
    file2.html
Another_Dir/
    file8.html
    Sub_Dir/
        file19.html

PHPMyAdmin http://trac.seagullproject.org/browser/branches/0.6-bugfix/lib/other/Zip.php'de kullanılan aynı PHP Zip sınıfını kullanıyorum . Sadece bir dosyadan ziyade bir dizini nasıl sıkıştıracağımı bilmiyorum. Şimdiye kadar sahip olduğum şeyler:

$aFiles = $this->da->getDirTree($target);
/* $aFiles is something like, path => filetime
Array
(
    [home] => 
    [home/file1.html] => 1251280379
    [home/file2.html] => 1251280377
    etc...
)

*/
$zip = & new Zip();
foreach( $aFiles as $fileLocation => $time ){
    $file = $target . "/" . $fileLocation;
    if ( is_file($file) ){
        $buffer = file_get_contents($file);
        $zip->addFile($buffer, $fileLocation);
    }
}
THEN_SOME_PHP_CLASS::toDownloadData($zip); // this bit works ok

ancak indirilen ilgili zip dosyasını açmaya çalıştığımda "işleme izin verilmiyor" mesajı alıyorum

Bu hata yalnızca mac'umda sıkıştırmayı açmaya çalıştığımda, komut satırını açtığımda dosya fermuarını açıyor tamam. İndirirken belirli bir içerik türü göndermem gerekiyor mu, şu anda 'application / zip'


Bu kod gerçekten işe yarıyor - ancak bazı nedenlerden dolayı onu Mac OS'de açamazsınız (CLI unzip'i kullanmadığınız sürece). Zip dosyası bilgisayarda çözülür.
ed209

Yanıtlar:


253

Burada, herhangi bir dosyayı veya dizini özyinelemeli olarak sıkıştırabilen basit bir işlev, yalnızca zip uzantısının yüklenmesi gerekir.

function Zip($source, $destination)
{
    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }

    $source = str_replace('\\', '/', realpath($source));

    if (is_dir($source) === true)
    {
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

        foreach ($files as $file)
        {
            $file = str_replace('\\', '/', $file);

            // Ignore "." and ".." folders
            if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
                continue;

            $file = realpath($file);

            if (is_dir($file) === true)
            {
                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

Şöyle diyelim:

Zip('/folder/to/compress/', './compressed.zip');

5
Çok iyi çalıştı, tek sorum betiğimin sıkıştırılacak dosyalara farklı bir yerden çalışması, bu nedenle 1. argümanı verdiğimde zip içinde tam dosya yolu konumunun kullanıldığına dair şu şekilde: C: \ wamp \ www \ export \ pkg-1211.191011 \ pkg-1211.191011.zip, bu tam iç içe klasör yapısı yeni arşivin içindedir. Yukarıdaki komut dosyasını, geldikleri tam yolu değil, yalnızca işaret ettiğim dosyaları ve dizinleri içerecek şekilde uyarlamanın bir yolu var mı?
danjah

4
@Danjah: Kodu güncelledim, şimdi hem * nix hem de Windows için çalışmalı.
Alix Axel 1811

6
Bunun neden file_get_contentsdizeleri kullandığını ve eklediğini merak ediyorum . zip dosyası doğrudan dosya eklemeyi desteklemiyor mu?
hakre

4
Hepiniz değiştirmek zorunda '/'olan DIRECTORY_SEPARATORelbette, Windows üzerinde çalışmasını sağlamak için. Aksi takdirde, ZIP'inizde tam yolu (sürücü adı dahil) bulursunuz, örn C:\Users\....
2013

3
Orijinal kod bozuk ve gereksiz. Yerine gerek yok //olan \ bu aslında pencerelerde foreach kırar olarak. Yerleşik olanı DIRECTORY_SEPARATORgerektiği gibi kullanırsanız, değiştirmenize gerek yoktur. /Bazı kullanıcıların sorun yaşamasına neden olan şey kodunun kodlanmasıydı . Neden boş bir arşiv aldığım konusunda kafam biraz karıştı. Revizyonum * nix ve Windows altında düzgün çalışacak.
DavidScherer

18

Yine bir başka yinelemeli dizin ağacı arşivleme, ZipArchive'ın bir uzantısı olarak uygulanmıştır. Bonus olarak, tek ifadeli bir ağaç sıkıştırma yardımcı işlevi dahildir. Diğer ZipArchive işlevlerinde olduğu gibi isteğe bağlı yer adı desteklenir. Eklenecek hata işleme kodu ...

class ExtendedZip extends ZipArchive {

    // Member function to add a whole file system subtree to the archive
    public function addTree($dirname, $localname = '') {
        if ($localname)
            $this->addEmptyDir($localname);
        $this->_addTree($dirname, $localname);
    }

    // Internal function, to recurse
    protected function _addTree($dirname, $localname) {
        $dir = opendir($dirname);
        while ($filename = readdir($dir)) {
            // Discard . and ..
            if ($filename == '.' || $filename == '..')
                continue;

            // Proceed according to type
            $path = $dirname . '/' . $filename;
            $localpath = $localname ? ($localname . '/' . $filename) : $filename;
            if (is_dir($path)) {
                // Directory: add & recurse
                $this->addEmptyDir($localpath);
                $this->_addTree($path, $localpath);
            }
            else if (is_file($path)) {
                // File: just add
                $this->addFile($path, $localpath);
            }
        }
        closedir($dir);
    }

    // Helper function
    public static function zipTree($dirname, $zipFilename, $flags = 0, $localname = '') {
        $zip = new self();
        $zip->open($zipFilename, $flags);
        $zip->addTree($dirname, $localname);
        $zip->close();
    }
}

// Example
ExtendedZip::zipTree('/foo/bar', '/tmp/archive.zip', ZipArchive::CREATE);

Güzel cevap Giorgio! Ağaç yapısı için pencerelerde Zip () 'den daha iyi sonuçlar verir. teşekkürler
RafaSashi

11

Düzenleme yaptığım Alix Axel üçüncü argrument almaya cevabını, bu üçüncü argrument ayarlarken trueana dizin altında yerine doğrudan daha zip klasöründe eklenecektir tüm dosyaları.

Zip dosyası varsa, dosya da silinecektir.

Misal:

Zip('/path/to/maindirectory','/path/to/compressed.zip',true);

Üçüncü belge truezip yapısı:

maindirectory
--- file 1
--- file 2
--- subdirectory 1
------ file 3
------ file 4
--- subdirectory 2
------ file 5
------ file 6

Üçüncü belge falseveya eksik zip yapısı:

file 1
file 2
subdirectory 1
--- file 3
--- file 4
subdirectory 2
--- file 5
--- file 6

Düzenlenen kod:

function Zip($source, $destination, $include_dir = false)
{

    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    if (file_exists($destination)) {
        unlink ($destination);
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }
    $source = str_replace('\\', '/', realpath($source));

    if (is_dir($source) === true)
    {

        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

        if ($include_dir) {

            $arr = explode("/",$source);
            $maindir = $arr[count($arr)- 1];

            $source = "";
            for ($i=0; $i < count($arr) - 1; $i++) { 
                $source .= '/' . $arr[$i];
            }

            $source = substr($source, 1);

            $zip->addEmptyDir($maindir);

        }

        foreach ($files as $file)
        {
            $file = str_replace('\\', '/', $file);

            // Ignore "." and ".." folders
            if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
                continue;

            $file = realpath($file);

            if (is_dir($file) === true)
            {
                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

Teşekkür ederim! Durumuma ana dizini eklemem gerekiyordu.
Kim Yığınlar

işleviniz çalışmıyor sadece ana (kök) dizin ekliyor ve hiçbir şey
Krishna Torque

Bunun uzun zaman önce cevaplandığını biliyorum. Orijinal ad yerine 'ana dizin' için özel bir ad olması mümkün mü?
Vaibhav Sidapara

@VaibhavSidapara $maindirTercih edilen adı değiştirerek bunun mümkün olabileceğine inanın .
user2019515

Harika cevap, bana çok yardımcı oldu. Hariç tutmaları dahil etmek için bu işleve dördüncü bir argüman ekledim. Son kodu bu soruya başka bir cevap olarak ekleyeceğim.
L. Ouellet

4

KULLANIM: thisfile.php? Dir =. / Yol / / klasörüne (Sıkıştırıldıktan sonra indirmeye de başlar :)

<?php
$exclude_some_files=
array(
        'mainfolder/folder1/filename.php',
        'mainfolder/folder5/otherfile.php'
);

//***************built from https://gist.github.com/ninadsp/6098467 ******
class ModifiedFlxZipArchive extends ZipArchive {
    public function addDirDoo($location, $name , $prohib_filenames=false) {
        if (!file_exists($location)) {  die("maybe file/folder path incorrect");}

        $this->addEmptyDir($name);
        $name .= '/';
        $location.= '/';
        $dir = opendir ($location);   // Read all Files in Dir

        while ($file = readdir($dir)){
            if ($file == '.' || $file == '..') continue;
            if (!in_array($name.$file,$prohib_filenames)){
                if (filetype( $location . $file) == 'dir'){
                    $this->addDirDoo($location . $file, $name . $file,$prohib_filenames );
                }
                else {
                    $this->addFile($location . $file, $name . $file);
                }
            }
        }
    }

    public function downld($zip_name){
        ob_get_clean();
        header("Pragma: public");   header("Expires: 0");   header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: private", false);    header("Content-Type: application/zip");
        header("Content-Disposition: attachment; filename=" . basename($zip_name) . ";" );
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: " . filesize($zip_name));
        readfile($zip_name);
    }
}

//set memory limits
set_time_limit(3000);
ini_set('max_execution_time', 3000);
ini_set('memory_limit','100M');
$new_zip_filename='down_zip_file_'.rand(1,1000000).'.zip';  
// Download action
if (isset($_GET['dir']))    {
    $za = new ModifiedFlxZipArchive;
    //create an archive
    if  ($za->open($new_zip_filename, ZipArchive::CREATE)) {
        $za->addDirDoo($_GET['dir'], basename($_GET['dir']), $exclude_some_files); $za->close();
    }else {die('cantttt');}

if (isset($_GET['dir']))    {
    $za = new ModifiedFlxZipArchive;
    //create an archive
    if  ($za->open($new_zip_filename, ZipArchive::CREATE)) {
        $za->addDirDoo($_GET['dir'], basename($_GET['dir']), $exclude_some_files); $za->close();
    }else {die('cantttt');}

    //download archive
    //on the same execution,this made problems in some hostings, so better redirect
    //$za -> downld($new_zip_filename);
    header("location:?fildown=".$new_zip_filename); exit;
}   
if (isset($_GET['fildown'])){
    $za = new ModifiedFlxZipArchive;
    $za -> downld($_GET['fildown']);
}
?>

2

Bu bağlantıyı deneyin <- BURADA DAHA FAZLA KAYNAK KODU

/** Include the Pear Library for Zip */
include ('Archive/Zip.php');

/** Create a Zipping Object...
* Name of zip file to be created..
* You can specify the path too */
$obj = new Archive_Zip('test.zip');
/**
* create a file array of Files to be Added in Zip
*/
$files = array('black.gif',
'blue.gif',
);

/**
* creating zip file..if success do something else do something...
* if Error in file creation ..it is either due to permission problem (Solution: give 777 to that folder)
* Or Corruption of File Problem..
*/

if ($obj->create($files)) {
// echo 'Created successfully!';
} else {
//echo 'Error in file creation';
}

?>; // We'll be outputting a ZIP
header('Content-type: application/zip');

// It will be called test.zip
header('Content-Disposition: attachment; filename="test.zip"');

//read a file and send
readfile('test.zip');
?>;

1

İşte benim kodum Zip için klasörleri ve alt klasörlerini ve dosyalarını ve zip formatında indirilebilir hale getirin

function zip()
 {
$source='path/folder'// Path To the folder;
$destination='path/folder/abc.zip'// Path to the file and file name ; 
$include_dir = false;
$archive = 'abc.zip'// File Name ;

if (!extension_loaded('zip') || !file_exists($source)) {
    return false;
}

if (file_exists($destination)) {
    unlink ($destination);
}

$zip = new ZipArchive;

if (!$zip->open($archive, ZipArchive::CREATE)) {
    return false;
}
$source = str_replace('\\', '/', realpath($source));
if (is_dir($source) === true)
{

    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

    if ($include_dir) {

        $arr = explode("/",$source);
        $maindir = $arr[count($arr)- 1];

        $source = "";
        for ($i=0; $i < count($arr) - 1; $i++) { 
            $source .= '/' . $arr[$i];
        }

        $source = substr($source, 1);

        $zip->addEmptyDir($maindir);

    }

    foreach ($files as $file)
    {
        $file = str_replace('\\', '/', $file);

        // Ignore "." and ".." folders
        if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
            continue;

        $file = realpath($file);

        if (is_dir($file) === true)
        {
            $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
        }
        else if (is_file($file) === true)
        {
            $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
        }
    }
}
else if (is_file($source) === true)
{
    $zip->addFromString(basename($source), file_get_contents($source));
}
$zip->close();

header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$archive);
header('Content-Length: '.filesize($archive));
readfile($archive);
unlink($archive);
}

Kodla İlgili Herhangi Bir Sorun Varsa Bana Bildirin.


0

Bu Zip işlevini Mac OSX'te çalıştırmam gerekiyordu

bu yüzden her zaman o sinir bozucu .DS_Store'u sıkıştırırdım.

Ek Ignore dosyalarını ekleyerek https://stackoverflow.com/users/2019515/user2019515'i uyarladım .

function zipIt($source, $destination, $include_dir = false, $additionalIgnoreFiles = array())
{
    // Ignore "." and ".." folders by default
    $defaultIgnoreFiles = array('.', '..');

    // include more files to ignore
    $ignoreFiles = array_merge($defaultIgnoreFiles, $additionalIgnoreFiles);

    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    if (file_exists($destination)) {
        unlink ($destination);
    }

    $zip = new ZipArchive();
        if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
        }
    $source = str_replace('\\', '/', realpath($source));

    if (is_dir($source) === true)
    {

        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

        if ($include_dir) {

            $arr = explode("/",$source);
            $maindir = $arr[count($arr)- 1];

            $source = "";
            for ($i=0; $i < count($arr) - 1; $i++) { 
                $source .= '/' . $arr[$i];
            }

            $source = substr($source, 1);

            $zip->addEmptyDir($maindir);

        }

        foreach ($files as $file)
        {
            $file = str_replace('\\', '/', $file);

            // purposely ignore files that are irrelevant
            if( in_array(substr($file, strrpos($file, '/')+1), $ignoreFiles) )
                continue;

            $file = realpath($file);

            if (is_dir($file) === true)
            {
                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

Yani .DS_Store'u zip'ten yok saymak için

zipIt ('/ yol / / klasör', '/path/to/compressed.zip', false, array ('. DS_Store'));


0

Harika bir çözüm ama Windows'um için bir değişiklik yapmam gerekiyor. Değiştirme kodunun altında

function Zip($source, $destination){

if (!extension_loaded('zip') || !file_exists($source)) {
    return false;
}

$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
    return false;
}

$source = str_replace('\\', '/', realpath($source));

if (is_dir($source) === true)
{
    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

    foreach ($files as $file)
    {
        $file = str_replace('\\', '/', $file);

        // Ignore "." and ".." folders
        if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
            continue;

        if (is_dir($file) === true)
        {
            $zip->addEmptyDir(str_replace($source . '/', '', $file));
        }
        else if (is_file($file) === true)
        {

            $str1 = str_replace($source . '/', '', '/'.$file);
            $zip->addFromString($str1, file_get_contents($file));

        }
    }
}
else if (is_file($source) === true)
{
    $zip->addFromString(basename($source), file_get_contents($source));
}

return $zip->close();
}

0

Bu kod hem Windows hem de linux için çalışır.

function Zip($source, $destination)
{
if (!extension_loaded('zip') || !file_exists($source)) {
    return false;
}

$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
    return false;
}

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
    DEFINE('DS', DIRECTORY_SEPARATOR); //for windows
} else {
    DEFINE('DS', '/'); //for linux
}


$source = str_replace('\\', DS, realpath($source));

if (is_dir($source) === true)
{
    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
    echo $source;
    foreach ($files as $file)
    {
        $file = str_replace('\\',DS, $file);
        // Ignore "." and ".." folders
        if( in_array(substr($file, strrpos($file, DS)+1), array('.', '..')) )
            continue;

        $file = realpath($file);

        if (is_dir($file) === true)
        {
            $zip->addEmptyDir(str_replace($source . DS, '', $file . DS));
        }
        else if (is_file($file) === true)
        {
            $zip->addFromString(str_replace($source . DS, '', $file), file_get_contents($file));
        }
        echo $source;
    }
}
else if (is_file($source) === true)
{
    $zip->addFromString(basename($source), file_get_contents($source));
}

return $zip->close();
}

0

İşte Alix'lerdeki sürüm tabanım, Windows üzerinde çalışıyor ve umarım * nix üzerinde de çalışıyor:

function addFolderToZip($source, $destination, $flags = ZIPARCHIVE::OVERWRITE)
{
    $source = realpath($source);
    $destination = realpath($destination);

    if (!file_exists($source)) {
        die("file does not exist: " . $source);
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, $flags )) {
        die("Cannot open zip archive: " . $destination);
    }

    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

    $sourceWithSeparator = $source . DIRECTORY_SEPARATOR;
    foreach ($files as $file)
    {
        // Ignore "." and ".." folders
        if(in_array(substr($file,strrpos($file, DIRECTORY_SEPARATOR)+1),array('.', '..')))
            continue;

        if (is_dir($file) === true)
        {
            $zip->addEmptyDir(
                str_replace($sourceWithSeparator, '', $file . DIRECTORY_SEPARATOR));
        }
        else if (is_file($file) === true)
        {
            $zip->addFile($file, str_replace($sourceWithSeparator, '', $file));
        }
    }

    return $zip->close();
}

0

İşte çok iyi çalışan basit, okunması kolay, özyinelemeli işlev:

function zip_r($from, $zip, $base=false) {
    if (!file_exists($from) OR !extension_loaded('zip')) {return false;}
    if (!$base) {$base = $from;}
    $base = trim($base, '/');
    $zip->addEmptyDir($base);
    $dir = opendir($from);
    while (false !== ($file = readdir($dir))) {
        if ($file == '.' OR $file == '..') {continue;}

        if (is_dir($from . '/' . $file)) {
            zip_r($from . '/' . $file, $zip, $base . '/' . $file);
        } else {
            $zip->addFile($from . '/' . $file, $base . '/' . $file);
        }
    }
    return $zip;
}
$from = "/path/to/folder";
$base = "basezipfolder";
$zip = new ZipArchive();
$zip->open('zipfile.zip', ZIPARCHIVE::CREATE);
$zip = zip_r($from, $zip, $base);
$zip->close();

0

@ User2019515 yanıtını takiben, arşivimdeki istisnaları işlemem gerekiyordu. işte bir örnekle sonuçlanan fonksiyon.

Zip İşlevi:

function Zip($source, $destination, $include_dir = false, $exclusions = false){
    // Remove existing archive
    if (file_exists($destination)) {
        unlink ($destination);
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }
    $source = str_replace('\\', '/', realpath($source));
    if (is_dir($source) === true){
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
        if ($include_dir) {
            $arr = explode("/",$source);
            $maindir = $arr[count($arr)- 1];
            $source = "";
            for ($i=0; $i < count($arr) - 1; $i++) {
                $source .= '/' . $arr[$i];
            }
            $source = substr($source, 1);
            $zip->addEmptyDir($maindir);
        }
        foreach ($files as $file){
            // Ignore "." and ".." folders
            $file = str_replace('\\', '/', $file);
            if(in_array(substr($file, strrpos($file, '/')+1), array('.', '..'))){
                continue;
            }

            // Add Exclusion
            if(($exclusions)&&(is_array($exclusions))){
                if(in_array(str_replace($source.'/', '', $file), $exclusions)){
                    continue;
                }
            }

            $file = realpath($file);
            if (is_dir($file) === true){
                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            } elseif (is_file($file) === true){
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    } elseif (is_file($source) === true){
        $zip->addFromString(basename($source), file_get_contents($source));
    }
    return $zip->close();
}

Bu nasıl kullanılır :

function backup(){
    $backup = 'tmp/backup-'.$this->site['version'].'.zip';
    $exclusions = [];
    // Excluding an entire directory
    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('tmp/'), RecursiveIteratorIterator::SELF_FIRST);
    foreach ($files as $file){
        array_push($exclusions,$file);
    }
    // Excluding a file
    array_push($exclusions,'config/config.php');
    // Excluding the backup file
    array_push($exclusions,$backup);
    $this->Zip('.',$backup, false, $exclusions);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.