file_put_contents - ไม่สามารถเปิดสตรีม: การอนุญาตถูกปฏิเสธ


100

ฉันกำลังพยายามเขียนแบบสอบถามไปยังไฟล์เพื่อแก้ไขข้อบกพร่อง ไฟล์อยู่ในdatabase/execute.php. ไฟล์ที่ฉันต้องการเขียนคือdatabase/queries.php.

ฉันกำลังพยายามใช้ file_put_contents('queries.txt', $query)

แต่ฉันกำลังได้รับ

file_put_contents (queries.txt) [function.file-put-contents]: ไม่สามารถเปิดสตรีม: การอนุญาตถูกปฏิเสธ

ฉันมีqueries.txtไฟล์ที่ chmod'd เป็น 777 ปัญหาคืออะไร


คุณได้ตรวจสอบphp.iniไฟล์เพื่อหาสิ่งที่อาจปฏิเสธการเข้าถึงไฟล์หรือไม่?
Hello71

2
ตรวจสอบให้แน่ใจว่าไดเรกทอรีนั้นถูกต้องแล้ว
Crayon Violent

1
ลองใช้ชื่อไฟล์สัมบูรณ์ อาจเป็นได้ว่าการตีความโฟลเดอร์ปัจจุบันของคุณแตกต่างจาก PHP
laher

1
คุณสามารถตรวจสอบสถานะ chmod อีกครั้งได้หรือไม่?
โยนาห์

1
มีรายการตรวจสอบการแก้ไขปัญหาสำหรับปัญหาประเภทนี้: stackoverflow.com/questions/36577020/…
Vic Seedoubleyew

คำตอบ:


73

ลองปรับการอนุญาตไดเร็กทอรี

จากเทอร์มินัลรันchmod 777 database(จากไดเร็กทอรีที่มีโฟลเดอร์ฐานข้อมูล)

apache และจะไม่มีใครเข้าถึงไดเร็กทอรีนี้ได้หากมีการ chmodd'ed อย่างถูกต้อง

สิ่งอื่นที่ต้องทำคือ echo "getcwd ()" นี่จะแสดงไดเร็กทอรีปัจจุบันและหากนี่ไม่ใช่ '/something.../database/' คุณจะต้องเปลี่ยน 'query.txt' เป็นเส้นทางแบบเต็มสำหรับเซิร์ฟเวอร์ของคุณ


107
777 ไม่ใช่ความเสี่ยงด้านความปลอดภัยหรือไม่?
hitautodestruct

12
ฉันสงสัยอย่างยิ่งว่าไม่เพียง แต่จะต้องเขียนไดเร็กทอรีเป้าหมายโดยบัญชีเซิร์ฟเวอร์เท่านั้น แต่ทุกไดเร็กทอรีหลักของไดเร็กทอรีเป้าหมายจะต้องอนุญาตให้บัญชีเซิร์ฟเวอร์เข้าไปในไดเร็กทอรี ฉันคิดว่านี่จะเป็น + x สำหรับสิทธิ์
Erhannis

2
ฉันทดลองทฤษฎีของ Erhannis กับ LAMP stack ใหม่และทฤษฎีนั้นถูกต้อง
thotheolh

4
@MajidFouladpour ฉันคิดว่าchmod +x /parent/directoryสำหรับทุกไดเรกทอรีหลักของเป้าหมาย chmod +x /parent/directory, chmod +x /parentฯลฯ
Erhannis

1
ขณะนี้มีรายการตรวจสอบการแก้ไขปัญหาสำหรับปัญหาประเภทนี้: stackoverflow.com/questions/36577020/…
Vic Seedoubleyew

19

ตัวเลือกอื่น ๆ

คือคุณสามารถสร้างApache (www-data)เจ้าของโฟลเดอร์ได้

sudo chown -R www-data:www-data /var/www

ที่ควรจะfile_put_contentsทำงานตอนนี้ แต่เพื่อความปลอดภัยยิ่งขึ้นคุณควรตั้งค่าการอนุญาตดังต่อไปนี้

find /var/www -type d -print0 | xargs -0 chmod 0755 # folder
find /var/www -type f -print0 | xargs -0 chmod 0644 # files
  • เปลี่ยน/var/wwwเป็นโฟลเดอร์รากของไฟล์ php ของคุณ

7

ตระหนักว่าตอนนี้ค่อนข้างเก่าแล้ว แต่ไม่จำเป็นต้องเขียนแบบสอบถามลงในไฟล์ด้วยตนเองเช่นนี้ MySQL มีการรองรับการบันทึกในตัวคุณเพียงแค่ต้องเปิดใช้งานภายในสภาพแวดล้อม dev ของคุณ

ดูเอกสารสำหรับ 'บันทึกการสืบค้นทั่วไป':

http://dev.mysql.com/doc/refman/5.1/en/query-log.html


4

การรวบรวมข้อมูลจากลิงค์นี้stackoverflow-image save ใช้ไม่ได้กับ chmod 777และจากผู้ใช้ azerafati และ Loek Bergman

หากคุณดูไฟล์ / etc / apache / envvars คุณจะเห็นสิ่งต่างๆเช่น:

export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data

Apache ทำงานภายใต้ชื่อผู้ใช้ 'www-data'

'0755' หมายถึงเจ้าของไฟล์สามารถอ่าน / เขียน / ดำเนินการได้ แต่กลุ่มและผู้ใช้อื่นไม่สามารถเขียนได้ ดังนั้นในเทอร์มินัล ur ให้ cd ไปยังโฟลเดอร์ที่มีโฟลเดอร์ 'images' ของคุณ จากนั้นพิมพ์:

find images -type d -exec chmod 0755 {} \;
find images -type f -exec chmod 0755 {} \;
sudo chown -R www-data:www-data images

คุณต้องเปลี่ยนสิทธิ์ก่อนเปลี่ยนเจ้าของ ป้อนรหัสผ่านของคุณเมื่อได้รับแจ้ง ซึ่งจะทำให้ "www-data" เป็นเจ้าของโฟลเดอร์รูปภาพ

การอัปโหลดของคุณควรใช้งานได้แล้ว


3

พวกฉันมีปัญหานี้มา 1 เดือนและทำทุกอย่างแล้วแต่ไม่สามารถแก้ไขได้ แต่ตอนนี้ฉันรู้วิธีแก้ปัญหาแล้ว

ฉันใช้โฮสติ้ง linux ที่ใช้ร่วมกันเมื่อผู้ดูแลระบบของฉันเปลี่ยน php เป็น 5.3 ฉันพบข้อผิดพลาดมากมายสำหรับโค้ด "file_put_contents" ลองทดสอบแผนของฉัน:

ในโฮสต์ของคุณให้สร้างไฟล์เช่น mytest.php และใส่รหัสนี้และบันทึก:

<?php        mail('Your-EMail','Email-Title','Email-Message');        ?>

เปิด URL "www.your-domain.com/mytest.php" หนึ่งครั้งจากนั้นตรวจสอบอีเมลของคุณ คุณควรมีอีเมลจากโฮสต์ของคุณพร้อมข้อมูลที่คุณป้อนใน mytest.php ตรวจสอบชื่อผู้ส่ง หากมาจากไม่มีใครคุณมีปัญหาเกี่ยวกับ "ปฏิเสธการอนุญาต" เนื่องจากมีบางอย่างไม่ได้กำหนดไว้และหากชื่อผู้ส่งเป็นเหมือนรหัสของฉัน: iietj8qy@hostname5.netly.net คุณไม่มีความน่าจะเป็น

ผู้ดูแลระบบของฉันเปลี่ยนเซิร์ฟเวอร์และติดตั้งโฮสต์อีกครั้งฉันคิดว่าปัญหาได้รับการแก้ไขแล้วบอกผู้ดูแลระบบโฮสต์ของคุณว่าฉันบอกอะไรคุณและพวกเขาอาจพบคำตอบ

หวังว่าจะช่วยคุณได้!


หายเกลี้ยง !! คุณพยายามจะพูดอะไร? หากคุณกำลังบอกว่าผู้ใช้ apache ไม่สามารถรับชื่อโฮสต์บนเซิร์ฟเวอร์ได้ (ใช้ร่วมกันหรืออะไรก็ได้) แสดงว่าถึงเวลาแล้วที่คุณจะพิจารณาตัวเลือกบริการโฮสติ้งอีกครั้ง
Fr0zenFyr

3

ฉันรู้ว่ามันเป็นคำถามที่เก่ามาก แต่ฉันต้องการเพิ่มคำตอบที่ดีพร้อมคำอธิบายเชิงลึก คุณจะต้องดำเนินการสองคำสั่งบน Ubuntu เหมือนระบบจากนั้นจึงทำงานได้อย่างมีเสน่ห์

สิทธิ์ใน Linux สามารถแสดงด้วยตัวเลขสามหลัก ตัวเลขตัวแรกกำหนดสิทธิ์ของเจ้าของไฟล์ ตัวเลขหลักที่สองคือสิทธิ์ของผู้ใช้เฉพาะกลุ่ม ตัวเลขหลักที่สามกำหนดสิทธิ์สำหรับผู้ใช้ทั้งหมดที่ไม่ใช่เจ้าของหรือสมาชิกของกลุ่ม

เว็บเซิร์ฟเวอร์ควรจะดำเนินการกับ id ที่เป็นสมาชิกของกลุ่ม เว็บเซิร์ฟเวอร์ไม่ควรทำงานด้วย id เดียวกับเจ้าของไฟล์และไดเร็กทอรี ใน Ubuntu รัน apache ภายใต้ id www-data ID นั้นควรเป็นสมาชิกของกลุ่มที่มีการระบุสิทธิ์

เพื่อให้ไดเร็กทอรีที่คุณต้องการเปลี่ยนเนื้อหาของไฟล์มีสิทธิ์ที่เหมาะสมให้ดำเนินการคำสั่ง:

find %DIR% -type d -exec chmod 770 {} \;

นั่นหมายความว่าในคำถามของ OP ว่าการอนุญาตสำหรับไดเรกทอรี% ROOT% / ฐานข้อมูลควรจะเปลี่ยนตาม ดังนั้นจึงเป็นเรื่องสำคัญที่จะต้องไม่มีไฟล์ภายในไดเร็กทอรีที่ไม่ควรถูกเปลี่ยนแปลงหรือลบออก ดังนั้นแนวทางปฏิบัติที่ดีที่สุดในการสร้างไดเร็กทอรีแยกต่างหากสำหรับไฟล์ที่ต้องเปลี่ยนแปลงเนื้อหา

สิทธิ์ในการอ่าน (4) สำหรับไดเร็กทอรีหมายถึงความสามารถในการรวบรวมไฟล์และไดเร็กทอรีทั้งหมดด้วยข้อมูลเมตาภายในไดเร็กทอรี สิทธิ์ในการเขียน (2) ให้สิทธิ์ในการเปลี่ยนแปลงเนื้อหาของไดเร็กทอรี หมายถึงการเพิ่มและลบไฟล์การเปลี่ยนสิทธิ์ ฯลฯ .. Execution permission (1) หมายความว่าคุณมีสิทธิ์เข้าไปในไดเร็กทอรีนั้น หากไม่มีสิ่งหลังจะเป็นไปไม่ได้ที่จะลงลึกเข้าไปในไดเร็กทอรี เว็บเซิร์ฟเวอร์ต้องการสิทธิ์ในการอ่านเขียนและดำเนินการเมื่อเนื้อหาของไฟล์ควรเปลี่ยนแปลง ดังนั้นความต้องการกลุ่มหลัก 7

คำสั่งที่สองอยู่ในคำถามของ OP:

find %DOCUMENT_ROOT%/database -type f -exec chmod 760 {} \;

จำเป็นต้องมีความสามารถในการอ่านและเขียนเอกสาร แต่ไม่จำเป็นต้องเรียกใช้ไฟล์ 7 มอบให้กับเจ้าของไฟล์ส่วน 6 ให้กับกลุ่ม เว็บเซิร์ฟเวอร์ไม่จำเป็นต้องมีสิทธิ์ในการเรียกใช้ไฟล์เพื่อเปลี่ยนแปลงเนื้อหา สิทธิ์การเขียนเหล่านั้นควรมอบให้กับไฟล์ในไดเร็กทอรีนั้นเท่านั้น

ผู้ใช้รายอื่นไม่ควรได้รับอนุญาตใด ๆ

สำหรับไดเร็กทอรีที่ไม่จำเป็นต้องเปลี่ยนไฟล์มีสิทธิ์กลุ่ม 5 เพียงพอ เอกสารเกี่ยวกับสิทธิ์และตัวอย่างบางส่วน:

https://wiki.debian.org/Permissions

https://www.linux.com/learn/tutorials/309527-understand-linux-file-permissions

http://www.linux.org/threads/file-permissions-chmod.4094/


1

สำหรับใครก็ตามที่ใช้ Ubuntu และได้รับข้อผิดพลาดนี้เมื่อโหลดเพจในเครื่อง แต่ไม่ได้ใช้บริการเว็บโฮสติ้ง

ฉันเพิ่งแก้ไขสิ่งนี้โดยการเปิด nautilus ( sudo nautilus) และคลิกขวาที่ไฟล์ที่คุณพยายามเปิดคลิกคุณสมบัติ> การตั้งค่า> และอ่านเขียนถึง 'คนอื่น ๆ '


1

หากคุณดึงคอมไพล์จากโลคัลไปยังเซิร์ฟเวอร์คุณจะต้องล้างแคชในบางครั้งเนื่องจากไฟล์มุมมองที่อัปโหลดพร้อมกับมัน / หรือไฟล์แคชอื่น ๆ

php artisan cache:clear

บางครั้งอาจเป็นเพียงเคล็ดลับหากแอปพลิเคชันของคุณทำงานก่อนที่จะดึงคอมไพล์


ใช่ดู: ชัดเจนใช้ได้สำหรับฉัน ไม่รู้ว่าทำไมถึงเกิดข้อผิดพลาดบ่อยขนาดนี้!
Douglas Hosea

0

มีปัญหาเดียวกัน ปัญหาของฉันถูกกำหนดให้มีการบังคับใช้ Selinux

ฉันยังคงได้รับข้อผิดพลาด "ล้มเหลวในการเปิดสตรีม: ปฏิเสธการอนุญาต" แม้ว่าจะ chmoding เป็น 777 และตรวจสอบให้แน่ใจว่าโฟลเดอร์หลักทั้งหมดมีสิทธิ์ดำเนินการสำหรับผู้ใช้ apache ปรากฎว่าปัญหาของฉันคือ Selinux ถูกตั้งค่าให้บังคับใช้ (ฉันใช้ centos7) นี่เป็น devbox ดังนั้นฉันจึงปิดมัน


0

สิ่งนี้สามารถแก้ไขได้ด้วยขั้นตอนต่อไปนี้:

1. $ php artisan cache:clear

2. $ sudo chmod -R 777 storage

3. $ composer dump-autoload

หวังว่าจะช่วยได้



-3

นี่คือทางออก ในการคัดลอก img จาก URL URL นี้:http://url/img.jpg

$image_Url=file_get_contents('http://url/img.jpg');

สร้างเส้นทางที่ต้องการโดยใช้ชื่อ .jpg

$file_destino_path="imagenes/my_image.jpg";

file_put_contents($file_destino_path, $image_Url)

-3

มี 2 ​​วิธีในการแก้ไขปัญหานี้
1. ใช้chmod 777 path-to-your-directory.
ถ้ามันไม่ได้ทำงานแล้ว
2. query.txtเพียงแค่ให้เส้นทางที่สมบูรณ์ของไฟล์ของคุณ


2
นี่เป็นการปฏิบัติที่ไม่ปลอดภัยอย่างน่ากลัวและแย่มาก นอกจากนี้ยังยากที่จะตรวจจับและแก้ไขเมื่อพัฒนาแอปพลิเคชันแบบกำหนดเองและสามารถมองข้ามได้ง่าย โปรดพิจารณาสิทธิ์ที่ถูกต้อง
ftrotter

-11

นอกจากนี้ตามที่กล่าวไว้file_put_contents man pageในphp.netโปรดระวังปัญหาการตั้งชื่อ

file_put_contents($dir."/file.txt", "hello");

อาจไม่ทำงาน (แม้ว่าจะถูกต้องกับไวยากรณ์) แต่

file_put_contents("$dir/file.txt", "hello");

ได้ผล ฉันพบสิ่งนี้บนเซิร์ฟเวอร์ที่ติดตั้ง php อื่น


17
สิ่งนี้ไม่ถูกต้อง $dir."/file.txt"มีฟังก์ชันเทียบเท่ากับ"$dir/file.txt"ในทุกกรณีโดยสมมติว่า$dirเป็นสตริง นอกจากนี้พฤติกรรมนี้ไม่ได้รับการบันทึกไว้ใน php.net ตามที่ Kivanc อ้าง
mattbasta
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.