PHP mkdir: ปัญหาการอนุญาตถูกปฏิเสธ


99

ฉันพยายามสร้างไดเร็กทอรีด้วยฟังก์ชัน PHP mkdir แต่ได้รับข้อผิดพลาดดังนี้: Warning: mkdir() [function.mkdir]: Permission denied in .... จะยุติปัญหาได้อย่างไร?


2
แพลตฟอร์ม / เว็บเซิร์ฟเวอร์ / ระบบปฏิบัติการ?
Salman A

1
ตรวจสอบคำถามนี้: http://stackoverflow.com/questions/13908722/php-unable-to-create-a-directory-with-mkdirฉันมีปัญหาเดียวกันและคำตอบที่นี่ช่วยแก้ปัญหาของฉันได้ หากคุณใช้งาน linux คำตอบเกี่ยวกับ SELinux อาจตรงกับคุณ
Lucas Madureira

คำตอบ:


174

ฉันรู้ว่านี่เป็นกระทู้เก่า แต่มันต้องการคำตอบที่ดีกว่านี้ คุณไม่จำเป็นต้องตั้งค่าสิทธิ์เป็น 777 นั่นเป็นปัญหาด้านความปลอดภัยเนื่องจากให้สิทธิ์การเข้าถึงแบบอ่านและเขียนไปทั่วโลก อาจเป็นไปได้ว่าผู้ใช้ apache ของคุณไม่มีสิทธิ์ในการอ่าน / เขียนบนไดเร็กทอรี

นี่คือสิ่งที่คุณทำใน Ubuntu

  1. ตรวจสอบว่าไฟล์ทั้งหมดเป็นของกลุ่ม Apache และผู้ใช้ ใน Ubuntu เป็นกลุ่มข้อมูล wwwและผู้ใช้

    chown -R www-data:www-data /path/to/webserver/www

  2. จากนั้นเปิดใช้งานสมาชิกทั้งหมดของกลุ่ม www-data เพื่ออ่านและเขียนไฟล์

    chmod -R g+rw /path/to/webserver/www

mkdir()ขณะนี้ฟังก์ชันphp ควรทำงานได้โดยไม่ส่งคืนข้อผิดพลาด


3
คำตอบที่ดี! หวังว่านี่จะขึ้นสู่อันดับต้น ๆ ของเพจเมื่อเวลาผ่านไป!
ผิดปกติสูง

18
นี้เป็นความคิดที่ดีมาก
Big McLargeHuge

Apache ต้องการสิทธิ์ในการเขียนสิ่งต่างๆเช่นแคชและบันทึก ... มันเป็นเพียงเรื่องของการปรับแต่ง
Manatax

@simpleengine สวัสดีฉันสังเกตเห็นคำตอบของคุณแล้ว .. ฉันกำลังประสบปัญหาเดียวกันกับโปรเจ็กต์ที่ฉันกำลังพยายามสร้างใน CodeIgnter และกำลังพัฒนาใน Ubuntu 14.14 Lts .. คุณช่วยอธิบายเพิ่มเติมเกี่ยวกับขั้นตอนที่ฉันต้องทำ ทำเพื่อแก้ไขข้อผิดพลาดนี้ ??? เพื่อให้ข้อมูลเพิ่มเติมแก่คุณ: เส้นทางสัมบูรณ์คือ/opt/lampp/htdocs/www/my-app/public/uploads.. โดยพื้นฐานแล้วสิ่งที่ฉันพยายามทำคือผู้ใช้ที่ลงชื่อเข้าใช้ทุกคนเพื่ออัปโหลดไฟล์ภายในโฟลเดอร์อัปโหลดและสร้างโฟลเดอร์อัลบั้ม (ซึ่งจะทำได้ด้วย php) เพื่อจัดเก็บรูปภาพ ..
ltdev

7
ฉันไม่ชอบผู้ใช้ที่พูดว่า "มันไม่ปลอดภัย" โดยไม่แสดงวิธีการที่ปลอดภัย
Cedric Ipkiss

38

คำตอบสำหรับผู้ที่พบสิ่งนี้ผ่านทาง Google ในอนาคต ฉันพบปัญหาเดียวกัน

หมายเหตุ: ฉันใช้ MAC OSX LION

สิ่งที่เกิดขึ้นคือ apache กำลังทำงานในฐานะผู้ใช้ "_www" และไม่มีสิทธิ์แก้ไขไฟล์ใด ๆ คุณจะสังเกตเห็นว่าไม่มีฟังก์ชันระบบไฟล์ทำงานผ่าน php

วิธีแก้ไข:

เปิดหน้าต่างตัวค้นหาและจากแถบเมนูเลือก Go> Go To Folder> / private / etc / apache2

ตอนนี้เปิด httpd.conf

หา:

User _www 
Group _www

เปลี่ยนชื่อผู้ใช้:

User <YOUR LOGIN USERNAME>

ตอนนี้รีสตาร์ท apache โดยเรียกใช้เทอร์มินัลแบบฟอร์มนี้:

sudo apachectl -k restart

หากยังไม่ได้ผลฉันต้องทำสิ่งต่อไปนี้ก่อนที่จะทำตามข้างต้น อาจเกี่ยวข้องกัน

เปิดเทอร์มินัลและเรียกใช้คำสั่งต่อไปนี้: (หมายเหตุไฟล์เว็บเซิร์ฟเวอร์ของฉันอยู่ที่ / Library / WebServer / www. เปลี่ยนตามตำแหน่งเว็บไซต์ของคุณ)

sudo chmod 775 /Library/WebServer/www
sudo chmod 775 /Library/WebServer/www/*

6
โซลูชันนี้ใช้งานได้ แต่อนุญาตให้ Apache สร้างความหายนะให้กับระบบของคุณหากมีคนมาเรียกใช้โค้ดที่เป็นอันตราย (เช่นผ่านการใช้ประโยชน์จาก Shellshock) อีกทางเลือกหนึ่งคือปล่อยให้ Apache ดำเนินการเป็น_wwwและสร้างกลุ่มสำหรับคุณและ Apache สร้างกลุ่มใหม่พูดว่าเรียกtrustedแล้วใส่ตัวเอง_wwwเข้าไป จากนั้นสร้างความไว้วางใจให้กับเจ้าของกลุ่มของไฟล์ทั้งหมดในไดเรกทอรีเอกสารเซิร์ฟเวอร์ของคุณ สุดท้ายทำchmod g+rwxตามความจำเป็นเฉพาะไฟล์ที่ Apache ต้องการเข้าถึงเพื่อให้trustedกลุ่มมีสิทธิ์แก้ไขไฟล์
Chris Middleton

3
เพียงแค่พูดเพื่อย้ำว่าคำตอบนี้เป็นความคิดที่ไม่ดี มีหลายเหตุผลที่ดีมากที่กระบวนการ apache เป็นของผู้ใช้วัตถุประสงค์พิเศษของตนเอง
danyamachine

16

อย่าตั้งค่าสิทธิ์เป็น 777 เมื่อใช้ mkdir ใน PHP

คำตอบเฉพาะลิงก์ไม่ถือว่าเป็นแนวทางปฏิบัติที่ดีใน StackOverflow แต่โดยทั่วไปแล้วไม่ควรปฏิบัติตามคำแนะนำที่ให้ไว้ในที่นี้

ฉันต้องการกลับไปใช้คำตอบที่ดีสำหรับคำถามที่คล้ายกันนี้ ฉันอ้าง:

โปรดหยุดแนะนำให้ใช้ 777 คุณกำลังทำให้ไฟล์ของคุณสามารถเขียนได้โดยทุกคนซึ่งหมายความว่าคุณสูญเสียความปลอดภัยทั้งหมดที่ระบบอนุญาตออกแบบมา หากคุณแนะนำสิ่งนี้ให้นึกถึงผลที่ตามมาที่อาจเกิดขึ้นกับเว็บเซิร์ฟเวอร์ที่มีการกำหนดค่าไม่ดีนั่นคือการ "แฮ็ก" เว็บไซต์จะกลายเป็นเรื่องง่ายอย่างเหลือเชื่อโดยการเขียนทับไฟล์ ดังนั้นอย่า


9

แก้ไขสิทธิ์ของไดเรกทอรีที่คุณพยายามที่จะสร้างไดเรกทอรีใน


ฉันเพิ่งแก้ไขปัญหาในคำถามเดิมโดยเปลี่ยนการอนุญาตไฟล์เป็น 755 ซ้ำโดยใช้ Filezilla คลิกขวาที่โฟลเดอร์หลักโดยสมมติว่าเป็นโฟลเดอร์ที่เก็บไฟล์ทั่วไปบางประเภทที่สามารถตั้งค่าการอนุญาต 755 ได้จากนั้นคุณสมบัติของไฟล์ -> ค่าตัวเลข -> 755 จากนั้นเลือก "เรียกคืนในไดเรกทอรีย่อย" ใช้เวลาสองสามนาทีในการเผยแพร่ผ่านไดเร็กทอรีย่อยหากคุณมีไฟล์จำนวนมาก จากนั้นลองอีกครั้ง
TARKUS

7

ฉันรู้ว่ากระทู้นี้เก่า แต่สักวันอาจจะช่วยใครสักคนได้

ปัญหาที่ PHP แจ้งว่า "ปฏิเสธการอนุญาต" สำหรับ mkdir () - เส้นทาง URL ไม่ถูกต้อง ดังนั้นในการแก้ไขสิ่งที่คุณต้องมีเพื่อให้ได้เส้นทางที่ถูกต้อง ฉันทำแบบนี้:

<?php

$root = $_SERVER["DOCUMENT_ROOT"];
$dir = $root . '/somefolder/';

if( !file_exists($dir) ) {
    mkdir($dir, 0755, true);
}

?>

1
เกิดขึ้นกับฉันเมื่อโอนไปยังโฮสต์ใหม่ (ซึ่งมี mysqlnd lol) ฉันลืมเปลี่ยนเป็นพา ธ โฮมไดเร็กทอรีแบบเต็มใหม่ ปรากฎว่าไม่ใช่ปัญหาการอนุญาต
JSG

2

คุณต้องมีสิทธิ์ระบบไฟล์เพื่อสร้างไดเร็กทอรี

ตัวอย่าง: ใน Ubuntu 10.04 apache (php) เรียกใช้เป็นผู้ใช้: www-data ในกลุ่ม: www-data

ความหมายผู้ใช้ www-data ต้องการการเข้าถึงเพื่อสร้างไดเร็กทอรี

คุณสามารถลองด้วยตัวเองโดยใช้: 'su www-data' เพื่อเป็นผู้ใช้ www-data

ในการแก้ไขอย่างรวดเร็วคุณสามารถทำได้: sudo chmod 777 my_parent_dir


14
chmod 0777จะให้การอ่านและเขียนเข้าถึงโลก! คุณไม่ควรให้คำแนะนำอะไรเช่นนั้น อย่างไรก็ตามคำแนะนำกับกลุ่มผู้ใช้ในปัจจุบันดีที่สุดที่นี่ :)
KingCrunch

1
ถ้าโลกนี้สามารถเข้าถึง OS ได้แน่นอน วิธีที่ดีกว่าคือ: sudo chown www-data: www-data my_parent_dir
Jon Skarpeteig

หรือปล่อยสิทธิ์ไว้เพียงอย่างเดียวและเพิ่ม www-data ไปยังกลุ่มไดเร็กทอรีหลัก
Marc B

0

สิ่งอื่นที่คุณทำได้คือไปที่: / etc / sudoers

มีการเพิ่มบรรทัดต่อไปนี้ซึ่งให้สิทธิ์แก่ผู้ใช้ www-data ALL = (ALL: ALL) ALL ทำไมต้องเป็น www-data? เนื่องจาก apache ทำงานโดยชื่อผู้ใช้นี้

ในกรณีที่ผู้ใช้ของคุณแตกต่างกันให้ลองใช้ชื่อผู้ใช้ ALL = (ALL: ALL) ALL

สิ่งนี้ได้ผลสำหรับฉัน


5
อย่าแก้ไขsudoersโดยตรง แต่เข้าสู่ระบบในฐานะรูทและใช้visudoคำสั่งte : ที่ตรวจสอบการเปลี่ยนแปลงใด ๆ เพื่อหลีกเลี่ยงการแก้ไขที่ผิดพลาดซึ่งอาจทำให้เกิดข้อผิดพลาดในการแยกวิเคราะห์เมื่อโหลดไฟล์ sudoers ซึ่งอาจทำให้คุณไม่มีอำนาจ (เนื่องจากไม่มีสิทธิ์ในการ เปลี่ยนแปลงอะไรก็ได้)
Elias Van Ootegem

วิธีค้นหาชื่อผู้ใช้ เช่น www-data? ฉันใช้ nginx แต่ไม่ได้ผล
robspin

1
@robspin ลองสิ่งนี้: ps aux | egrep '(nginx)'
maxwells

0

เนื่องจากคุณใช้เครื่อง Mac คุณสามารถเพิ่มตัวเองในกลุ่ม _www (กลุ่มผู้ใช้ apache) บนเครื่อง Mac ของคุณได้:

sudo dseditgroup -o edit -a $USER -t user _www

และเพิ่มผู้ใช้ _www ในกลุ่มล้อซึ่งดูเหมือนจะเป็นสิ่งที่ mac สร้างไฟล์เป็น:

sudo dseditgroup -o edit -a _www -t user wheel

0

ฉันมีปัญหานี้ในตอนนี้ทางออกที่ดีที่สุดที่ฉันสามารถมอบให้คุณได้ในตอนนี้ (แม้ว่าคุณจะไม่ได้ใส่รหัสใด ๆ ก็ตาม) จะเป็น:

  1. ตรวจสอบว่าคุณตั้งชื่อโฟลเดอร์ปลายทางของคุณอย่างไรเช่น new_folder (บางครั้งอาจทำให้เกิดข้อผิดพลาดในการอนุญาตเนื่องจากโฮสต์ส่วนใหญ่ไม่อนุญาตให้สร้างชื่อที่ใช้เครื่องหมายขีดล่างเส้นประ ฯลฯ ในขณะทำงาน) มันได้ผลสำหรับฉัน
  2. หากคุณใช้คำสั่งแบบเรียกซ้ำเพื่อสร้างโฟลเดอร์ย่อยอย่าลืมใส่ 0755 (อย่าลืมรวม 0 ที่จุดเริ่มต้น) ในคำสั่ง mkdir เช่น:

    if(!file_exists($output)){
        if (!mkdir($output, 0755, true)) {//0755
            die('Failed to create folders...');
        }
    
    }
    

ตอนนี้ใช้ได้ผลกับฉันด้วย


3
777 เป็นปัญหาด้านความปลอดภัย
MaicolBen

แก้ไขเมื่อตอนนี้เป็น 0755
arungisyadi

0

หากคุณใช้ LINUX ขั้นแรกให้ตรวจสอบผู้ใช้ของ apache เนื่องจากในบางส่วนอาจแตกต่างกัน

egrep -i '^user|^group' /etc/httpd/conf/httpd.conf 

สมมติว่าผลลัพธ์คือ "http" ทำการ folowwing เพียงจำไว้ว่าเปลี่ยน path_to_folder เป็นโฟลเดอร์ path:

chown -R http:http path_to_folder
chmod -R g+rw path_to_folder

0

ตรวจสอบว่าไม่ใช่ปัญหากับ umask หรือไม่

if (!function_exists('mkdir_r')) {
    /**
     * create directory recursively
     * @param $dirName
     * @param int $rights
     * @param string $dir_separator
     * @return bool
     */
    function mkdir_r($dirName, $rights = 0744, $dir_separator = DIRECTORY_SEPARATOR) {
        $dirs = explode($dir_separator, $dirName);
        $dir = '';
        $created = false;
        foreach ($dirs as $part) {
            $dir .= $part . $dir_separator;
            if (!is_dir($dir) && strlen($dir) > 0) {
                $created = mkdir($dir, $rights);
            }
        }
        return $created;
    }
}

if (!function_exists('ensure_dir')) {
    /**
     * ensure directory exist if not create 
     * @param $dir_path
     * @param int $mode
     * @param bool $use_mask
     * @param int $mask
     * @return bool
     */
    function ensure_dir($dir_path, $mode = 0744, $use_mask = true, $mask = 0002) {
        // set mask 
        $old_mask = $use_mask && $mask != null
            ? umask($mask)
            : null;
        try {
            return is_dir($dir_path) || mkdir_r($dir_path, $mode);
        } finally {
            if ($use_mask && $old_mask != null) {
                // restore original
                umask($old_mask);
            }
        }
    }
}

0

หลังจากที่คุณติดตั้งเซิร์ฟเวอร์ ftp แล้วsudo apt-get install vsftpdคุณจะต้องกำหนดค่า ในการเปิดใช้งานการเข้าถึงการเขียนคุณต้องแก้ไข/etc/vsftpd.confไฟล์และยกเลิกการใส่เครื่องหมาย

#write_enable=YES

บรรทัดจึงควรอ่าน

write_enable=YES

บันทึกไฟล์และรีสตาร์ทvsftpdด้วยsudo service vsftpd restart .

สำหรับตัวเลือกการกำหนดค่าอื่น ๆ โปรดดูเอกสารนี้หรือman vsftpd.conf


0

ข้อผิดพลาดนี้เกิดขึ้นหากคุณใช้เส้นทางที่ไม่ถูกต้อง

เช่น:

ฉันใช้ระบบอูบุนตูและชื่อโฟลเดอร์โปรเจ็กต์ของฉันคือ'myproject'

สมมติว่าฉันมีไดเร็กทอรีmyproject / public / reportและต้องการสร้างโฟลเดอร์ใหม่ที่เรียกว่าorders

จากนั้นฉันต้องการเส้นทางทั้งหมดที่มีโครงการของฉันอยู่ คุณสามารถรับเส้นทางด้วยคำสั่ง PWD

ดังนั้นเส้นทางรากของฉันจะเป็น = '/ home / htdocs / myproject /'

$ dir = '/ home / htdocs / myproject / public / report / Orders';

if (!is_dir($dir)) {
   mkdir($dir, 0775, true);
}

มันจะทำงานสำหรับคุณ !! สนุก !!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.