পিএইচপি ব্যবহার করে কোনও ফাইল পরিবেশন করার দ্রুততম উপায়


98

আমি একটি ফাংশন একসাথে রাখার চেষ্টা করছি যা একটি ফাইল পাথ গ্রহণ করে, এটি কী তা চিহ্নিত করে, উপযুক্ত শিরোনামগুলি সেট করে, এবং অ্যাপাচি যেমন ঠিক তেমন পরিবেশন করে।

আমি এটি করার কারণটি কারণ ফাইলটি পরিবেশন করার আগে আমাকে অনুরোধ সম্পর্কে কিছু তথ্য প্রক্রিয়া করার জন্য পিএইচপি ব্যবহার করতে হবে।

গতি সমালোচনা

ভার্চুয়াল () কোনও বিকল্প নয়

একটি ভাগ করা হোস্টিং পরিবেশে অবশ্যই কাজ করা উচিত যেখানে ব্যবহারকারীর ওয়েব সার্ভারের কোনও নিয়ন্ত্রণ নেই (অ্যাপাচি / এনগিনেক্স, ইত্যাদি)

আমি এ পর্যন্ত যা পেয়েছি তা এখানে:

File::output($path);

<?php
class File {
static function output($path) {
    // Check if the file exists
    if(!File::exists($path)) {
        header('HTTP/1.0 404 Not Found');
        exit();
    }

    // Set the content-type header
    header('Content-Type: '.File::mimeType($path));

    // Handle caching
    $fileModificationTime = gmdate('D, d M Y H:i:s', File::modificationTime($path)).' GMT';
    $headers = getallheaders();
    if(isset($headers['If-Modified-Since']) && $headers['If-Modified-Since'] == $fileModificationTime) {
        header('HTTP/1.1 304 Not Modified');
        exit();
    }
    header('Last-Modified: '.$fileModificationTime);

    // Read the file
    readfile($path);

    exit();
}

static function mimeType($path) {
    preg_match("|\.([a-z0-9]{2,4})$|i", $path, $fileSuffix);

    switch(strtolower($fileSuffix[1])) {
        case 'js' :
            return 'application/x-javascript';
        case 'json' :
            return 'application/json';
        case 'jpg' :
        case 'jpeg' :
        case 'jpe' :
            return 'image/jpg';
        case 'png' :
        case 'gif' :
        case 'bmp' :
        case 'tiff' :
            return 'image/'.strtolower($fileSuffix[1]);
        case 'css' :
            return 'text/css';
        case 'xml' :
            return 'application/xml';
        case 'doc' :
        case 'docx' :
            return 'application/msword';
        case 'xls' :
        case 'xlt' :
        case 'xlm' :
        case 'xld' :
        case 'xla' :
        case 'xlc' :
        case 'xlw' :
        case 'xll' :
            return 'application/vnd.ms-excel';
        case 'ppt' :
        case 'pps' :
            return 'application/vnd.ms-powerpoint';
        case 'rtf' :
            return 'application/rtf';
        case 'pdf' :
            return 'application/pdf';
        case 'html' :
        case 'htm' :
        case 'php' :
            return 'text/html';
        case 'txt' :
            return 'text/plain';
        case 'mpeg' :
        case 'mpg' :
        case 'mpe' :
            return 'video/mpeg';
        case 'mp3' :
            return 'audio/mpeg3';
        case 'wav' :
            return 'audio/wav';
        case 'aiff' :
        case 'aif' :
            return 'audio/aiff';
        case 'avi' :
            return 'video/msvideo';
        case 'wmv' :
            return 'video/x-ms-wmv';
        case 'mov' :
            return 'video/quicktime';
        case 'zip' :
            return 'application/zip';
        case 'tar' :
            return 'application/x-tar';
        case 'swf' :
            return 'application/x-shockwave-flash';
        default :
            if(function_exists('mime_content_type')) {
                $fileSuffix = mime_content_type($path);
            }
            return 'unknown/' . trim($fileSuffix[0], '.');
    }
}
}
?>

10
কেন আপনি আপাচে এই কাজ করতে দিচ্ছেন না? পিএইচপি ইন্টারপ্রেটার শুরু করার চেয়ে এটি সর্বদা যথেষ্ট দ্রুত হতে চলেছে ...
বিলি ওনেল

4
ফাইলটি আউটপুট দেওয়ার আগে আমাকে অনুরোধটি প্রক্রিয়া করতে হবে এবং ডাটাবেসে কিছু তথ্য সংরক্ষণ করতে হবে।
কर्क ওউইমেট

4
আমি আরো ব্যয়বহুল রেগুলার এক্সপ্রেশনের ছাড়া এক্সটেনশানটি পান একটি উপায় সুপারিশ করতে পারি: $extension = end(explode(".", $pathToFile)), অথবা আপনি substr এবং strrpos সঙ্গে এটি করতে পারেন: $extension = substr($pathToFile, strrpos($pathToFile, '.'))। এছাড়াও, mime_content_type()$mimetype = exec("file -bi '$pathToFile'", $output);
ফ্যালব্যাক

দ্রুততম বলতে কী বুঝ ? দ্রুততম ডাউনলোডের সময়?
অ্যালিক্স অ্যাক্সেল

উত্তর:


140

আমার পূর্ববর্তী উত্তরটি আংশিক ছিল এবং ভাল নথিভুক্ত ছিল না, এটির থেকে এবং আলোচনায় থাকা অন্যদের সমাধানের সংক্ষিপ্তসার সহ এখানে একটি আপডেট রয়েছে।

সমাধানগুলি সর্বোত্তম সমাধান থেকে খারাপের দিকেও অর্ডার করা হয় তবে সেই সমাধান থেকে যা ওয়েব সার্ভারের উপর সবচেয়ে বেশি নিয়ন্ত্রণের প্রয়োজন যার কাছে কম প্রয়োজন to এমন এক সমাধানের সহজ উপায় বলে মনে হয় না যা উভয়ই দ্রুত এবং কাজ করে is


এক্স-সেন্ডফিল শিরোনাম ব্যবহার করে

অন্যদের দ্বারা নথিবদ্ধ হিসাবে এটি আসলে সর্বোত্তম উপায়। ভিত্তিটি হ'ল আপনি পিএইচপিতে আপনার অ্যাক্সেস নিয়ন্ত্রণটি করেন এবং তারপরে ফাইলটি নিজে পাঠানোর পরিবর্তে আপনি ওয়েব সার্ভারকে এটি করতে বলে দেন।

বেসিক পিএইচপি কোডটি হ'ল:

header("X-Sendfile: $file_name");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($file_name) . '"');

$file_nameফাইল সিস্টেমের পুরো পথটি কোথায় ।

এই সমাধানটির মূল সমস্যাটি হ'ল এটি ওয়েব সার্ভারের দ্বারা অনুমোদিত হতে হবে এবং এটি ডিফল্ট (অ্যাপাচি) দ্বারা ইনস্টল করা হয়নি, ডিফল্টরূপে সক্রিয় নয় (লাইটটিপিডি) বা একটি নির্দিষ্ট কনফিগারেশন (এনজিনেক্স) প্রয়োজন।

আপাচে

অ্যাপাচের অধীনে আপনি যদি mod_php ব্যবহার করেন তবে আপনাকে Mod_xsendfile নামক একটি মডিউল ইনস্টল করতে হবে তারপরে এটি কনফিগার করুন (হয় অ্যাপাচি কনফিগারেশনে বা .htaccess যদি আপনি অনুমতি দেন)

XSendFile on
XSendFilePath /home/www/example.com/htdocs/files/

এই মডিউলটির সাহায্যে ফাইলের পথটি নিখুঁত বা নির্দিষ্ট বর্ণনার সাথে সম্পর্কিত হতে পারে XSendFilePath

লাইটটিপিডি

মোড_ফেসটিকি এটির সাহায্যে কনফিগার করা থাকলে সমর্থন করে

"allow-x-send-file" => "enable" 

বৈশিষ্ট্যের জন্য ডকুমেন্টেশনগুলি হাইটার ডকুমেন্ট লাইটটিপিডি উইকিতে রয়েছেX-LIGHTTPD-send-file তবে X-Sendfileনামটিও কাজ করে

এনগিনেক্স

এনগিনেক্সে আপনি শিরোনামটি ব্যবহার করতে পারবেন না X-Sendfileআপনাকে অবশ্যই তাদের নিজস্ব শিরোলেখ ব্যবহার করতে হবে যা নামকরণ করা হয়েছে X-Accel-Redirect। এটি ডিফল্টরূপে সক্ষম করা হয়েছে এবং কেবলমাত্র পার্থক্যটি হ'ল এটির যুক্তিটি কোনও ইউআরআই হওয়া উচিত ফাইল সিস্টেম নয়। ফলাফলটি হ'ল ক্লায়েন্টদের আসল ফাইল ইউআরএল সন্ধান করতে এবং সরাসরি এটিতে যেতে এড়াতে আপনার কনফিগারেশনের অভ্যন্তরীণ হিসাবে চিহ্নিত একটি অবস্থান অবশ্যই আপনাকে নির্ধারণ করতে হবে, তাদের উইকিতে এটির একটি ভাল ব্যাখ্যা রয়েছে ।

সিমলিঙ্কস এবং অবস্থান শিরোনাম

আপনি সিমলিঙ্কগুলি ব্যবহার করতে পারেন এবং সেগুলিতে পুনর্নির্দেশ করতে পারেন , যখন কোনও ব্যবহারকারী কোনও ফাইল অ্যাক্সেস করার জন্য অনুমোদিত হয় এবং ব্যবহারকারীকে এটিতে পুনঃনির্দেশ করে: কেবল এলোমেলো নামের সাথে আপনার ফাইলে সিমলিংক তৈরি করতে পারেন:

header("Location: " . $url_of_symlink);

স্পষ্টতই আপনার ছাঁটাই করার একটি উপায় প্রয়োজন যখন তাদের তৈরির স্ক্রিপ্টটি কল করা হবে বা ক্রোনের মাধ্যমে (মেশিনে যদি আপনার অ্যাক্সেস থাকে বা অন্য কোনও ওয়েবক্রোন পরিষেবা দিয়ে অন্যথায়)

অ্যাপাচি অধীনে আপনি FollowSymLinksএকটি .htaccessবা অ্যাপাচি কনফিগারেশন সক্ষম করতে সক্ষম হতে হবে ।

আইপি এবং অবস্থান শিরোনাম দ্বারা অ্যাক্সেস নিয়ন্ত্রণ control

আরেকটি হ্যাক হ'ল পিএইচপি থেকে অ্যাপাচি অ্যাক্সেস ফাইল উত্পন্ন করা যা স্পষ্ট ব্যবহারকারী আইপি ব্যবহার করে। অ্যাপাচের অধীনে এর অর্থ mod_authz_host( mod_access) Allow fromকমান্ড ব্যবহার করা ।

সমস্যাটি হ'ল ফাইলটিতে অ্যাক্সেস লক করা (একসাথে একাধিক ব্যবহারকারী একই সাথে এটি করতে চাইতে পারে) অমূলক কাজ নয় এবং কিছু ব্যবহারকারী দীর্ঘ সময়ের জন্য অপেক্ষা করতে পারে lead এবং আপনার এখনও ফাইলটি ছাঁটাই করা দরকার।

স্পষ্টতই আর একটি সমস্যা হ'ল একই আইপিটির পিছনে থাকা একাধিক লোকেরা সম্ভবত ফাইলটি অ্যাক্সেস করতে পারে।

যখন অন্য সব কিছু ব্যর্থ হয়

আপনার যদি আপনার ওয়েব সার্ভারটি আপনাকে সহায়তা করার জন্য সত্যই কোনও উপায় না পায় তবে বাকি একমাত্র সমাধানটি বর্তমানে ব্যবহৃত সমস্ত পিএইচপি সংস্করণগুলিতে এটি রিডফাইলে পাওয়া যায় এবং এটি বেশ ভালভাবে কাজ করে (তবে সত্যই কার্যকর নয়)।


সংমিশ্রণ সমাধান

ঠিক আছে, আপনার পিএইচপি কোডটি সর্বত্র ব্যবহারযোগ্য হতে চাইলে খুব দ্রুত ফাইল প্রেরণের সর্বোত্তম উপায়টি হ'ল ওয়েব সার্ভারের উপর নির্ভর করে কীভাবে এটি সক্রিয় করতে হবে এবং আপনার ইনস্টলটিতে কোনও স্বয়ংক্রিয় সনাক্তকরণের নির্দেশাবলী সহ কোথাও একটি কনফিগার করার বিকল্প রয়েছে to লিপি.

এটি অনেকটা সফ্টওয়্যার-এর জন্য যা করা হয় তার সাথে বেশ মিল

  • ইউআরএল পরিষ্কার করুন ( mod_rewriteঅ্যাপাচে)
  • ক্রিপ্টো ফাংশন ( mcryptপিএইচপি মডিউল)
  • মাল্টিবাইট স্ট্রিং সমর্থন ( mbstringপিএইচপি মডিউল)

কিছু করার আগে পিএইচপি কাজ (ডাটাবেসের বিরুদ্ধে কুকি / অন্যান্য জিইটি / পোষ্ট প্যারামগুলি পরীক্ষা করুন) করতে সমস্যা আছে কি header("Location: " . $path);?
আফ্রিজা এন। সংক্ষিপ্ত

4
এই জাতীয় পদক্ষেপের জন্য কোনও সমস্যা নেই, যে বিষয়টি সম্পর্কে আপনাকে সতর্কতা অবলম্বন করা উচিত সেগুলি বিষয়বস্তু (মুদ্রণ, প্রতিধ্বনি) প্রেরণ করা হয় কারণ কোনও শিরোনামের আগে শিরোনাম অবশ্যই আসতে হবে এবং এই শিরোনাম পাঠানোর পরে জিনিসগুলি করা উচিত, এটি তাত্ক্ষণিক পুনঃনির্দেশ এবং কোড হওয়ার পরে নয় বেশিরভাগ সময় কার্যকর করা হয় তবে ব্রাউজার সংযোগটি কাটবে না এমন কোনও গ্যারান্টি আপনার নেই।
জুলিয়েন রোনাকাগলিয়া

জর্ডস: আমি জানতাম না যে অ্যাপাচিও এটি সমর্থন করে, আমি সময় পেলে এটি আমার উত্তরটিতে যুক্ত করব। এটির সাথে একমাত্র সমস্যা হ'ল আমি একীভূত নই (উদাহরণস্বরূপ এক্স-অ্যাক্সেল-রিডাইরেক্ট এনজিনেক্স) সুতরাং সার্ভারটি যদি সমর্থন না করে তবে দ্বিতীয় সমাধান প্রয়োজন। তবে আমার উত্তরে এটি যুক্ত করা উচিত।
জুলিয়েন রোনাকাগলিয়া

আমি .htaccess কে XSendFilePath নিয়ন্ত্রণ করতে অনুমতি দিতে পারি?
ভায়ানা

4
@ কেইন আমি মনে করি না আপনি পারবেন। tn123.org/mod_xsendfile নেই XSendFilePath বিকল্পের জন্য প্রেক্ষাপটে তালিকা .htaccess না
cheshirekow

33

দ্রুততম উপায়: করবেন না। দেখব nginx জন্য x- sendfile হেডার সেখানে অন্যান্য ওয়েব সার্ভারের জন্য অনুরূপ জিনিস। এর অর্থ আপনি পিএইচপি তে অ্যাক্সেস নিয়ন্ত্রণ ইত্যাদি করতে পারেন তবে সেটির জন্য ডিজাইন করা ওয়েব সার্ভারে ফাইলটি প্রকৃত প্রেরণে অর্পণ করতে পারেন।

পিএস: পিএনএইচপি-তে ফাইল পড়ার এবং প্রেরণের তুলনায় আমি এনজিনেক্সের সাহায্যে এটি ব্যবহার করা আরও কতটা দক্ষ তা নিয়ে ভাবছিলাম ঠিক। ১০০ জন লোক যদি কোনও ফাইল ডাউনলোড করছে: ভাবুন: পিএইচপি + অ্যাপাচি সহ উদার হচ্ছেন, ঠিক সেখানে র্যামের ১০০ * ১৫ এমবি = ১.৫ জিবি (প্রায় আমাকে গুলি করুন)। এনগিনেক্স কেবল ফাইলটি কার্নেলে প্রেরণ বন্ধ করবে এবং তারপরে এটি সরাসরি ডিস্ক থেকে নেটওয়ার্ক বাফারে লোড করা হবে। দ্রুত!

পিপিএস: এবং, এই পদ্ধতিটির সাহায্যে আপনি এখনও চাইলে সমস্ত অ্যাক্সেস নিয়ন্ত্রণ, ডাটাবেস স্টাফ করতে পারেন।


4
আমাকে শুধু যোগ যে এটি এ্যাপাচি জন্য বিদ্যমান করা যাক: jasny.net/articles/how-i-php-x-sendfile । আপনি স্ক্রিপ্টটি সার্ভারটি স্নিগ্ধ করতে এবং উপযুক্ত হেডারগুলি প্রেরণ করতে পারেন। যদি কারও অস্তিত্ব থাকে না (এবং প্রশ্ন অনুসারে সার্ভারের উপরে ব্যবহারকারীর কোনও নিয়ন্ত্রণ নেই), ফিরে যান একটি স্বাভাবিক অবস্থায়readfile()
ফ্যানিস হাটজিডাকিস

এখন এটি কেবল দুর্দান্ত - আমি খুব শীঘ্রই এটি চেষ্টা করব।
গ্রেগ ডাব্লু

4
ও ঋণ যেখানে ক্রেডিট কারণে জন্য, lighttpd এই বাস্তবায়ন প্রথম ওয়েব সার্ভার ছিল (এবং বাকি এটা কপি, যা জরিমানা যেহেতু এটি একটি মহান ধারণা কিন্তু যেখানে দেনা আছে সেখানে কারণে দেব।) ...
ircmaxell

4
এই উত্তরটি অগ্রাহ্য হতে থাকে, তবে এটি এমন পরিবেশে কাজ করবে না যেখানে ওয়েব সার্ভার এবং এর সেটিংস ব্যবহারকারীর নিয়ন্ত্রণের বাইরে রয়েছে।
কर्क ওউইমেট

আমি এই উত্তরটি পোস্ট করার পরে আপনি এটি আপনার প্রশ্নের সাথে যুক্ত করেছেন। এবং যদি কর্মক্ষমতা কোনও সমস্যা হয় তবে ওয়েব সার্ভারটি আপনার নিয়ন্ত্রণের মধ্যে থাকতে হবে।
জর্ডস

23

এখানে একটি খাঁটি পিএইচপি সমাধান হয়। আমি আমার ব্যক্তিগত কাঠামো থেকে নিম্নলিখিত ফাংশনটি রূপান্তর করেছি :

function Download($path, $speed = null, $multipart = true)
{
    while (ob_get_level() > 0)
    {
        ob_end_clean();
    }

    if (is_file($path = realpath($path)) === true)
    {
        $file = @fopen($path, 'rb');
        $size = sprintf('%u', filesize($path));
        $speed = (empty($speed) === true) ? 1024 : floatval($speed);

        if (is_resource($file) === true)
        {
            set_time_limit(0);

            if (strlen(session_id()) > 0)
            {
                session_write_close();
            }

            if ($multipart === true)
            {
                $range = array(0, $size - 1);

                if (array_key_exists('HTTP_RANGE', $_SERVER) === true)
                {
                    $range = array_map('intval', explode('-', preg_replace('~.*=([^,]*).*~', '$1', $_SERVER['HTTP_RANGE'])));

                    if (empty($range[1]) === true)
                    {
                        $range[1] = $size - 1;
                    }

                    foreach ($range as $key => $value)
                    {
                        $range[$key] = max(0, min($value, $size - 1));
                    }

                    if (($range[0] > 0) || ($range[1] < ($size - 1)))
                    {
                        header(sprintf('%s %03u %s', 'HTTP/1.1', 206, 'Partial Content'), true, 206);
                    }
                }

                header('Accept-Ranges: bytes');
                header('Content-Range: bytes ' . sprintf('%u-%u/%u', $range[0], $range[1], $size));
            }

            else
            {
                $range = array(0, $size - 1);
            }

            header('Pragma: public');
            header('Cache-Control: public, no-cache');
            header('Content-Type: application/octet-stream');
            header('Content-Length: ' . sprintf('%u', $range[1] - $range[0] + 1));
            header('Content-Disposition: attachment; filename="' . basename($path) . '"');
            header('Content-Transfer-Encoding: binary');

            if ($range[0] > 0)
            {
                fseek($file, $range[0]);
            }

            while ((feof($file) !== true) && (connection_status() === CONNECTION_NORMAL))
            {
                echo fread($file, round($speed * 1024)); flush(); sleep(1);
            }

            fclose($file);
        }

        exit();
    }

    else
    {
        header(sprintf('%s %03u %s', 'HTTP/1.1', 404, 'Not Found'), true, 404);
    }

    return false;
}

কোডটি যতটা সম্ভব দক্ষ, এটি সেশন হ্যান্ডলারটি বন্ধ করে দেয় যাতে অন্যান্য পিএইচপি স্ক্রিপ্ট একই ব্যবহারকারী / সেশনের জন্য একই সাথে চলতে পারে। এটি ব্যাপ্তিগুলিতে রেঞ্জিং ডাউনলোডগুলিও সমর্থন করে (এটি আমারও সন্দেহ হয় যে অ্যাপাচি ডিফল্টরূপে আমার সন্দেহ হয়), যাতে লোকেরা ডাউনলোডগুলি বিরতি / পুনঃসূচনা করতে এবং ডাউনলোড ত্বরণক দ্বারা উচ্চতর ডাউনলোডের গতি থেকে উপকৃত হতে পারে। এটি আপনাকে সর্বোচ্চ গতি (কেবিপিএসে) নির্দিষ্ট করতে দেয় যেখানে ডাউনলোড (অংশ) $speedআর্গুমেন্টের মাধ্যমে পরিবেশন করা উচিত ।


4
স্পষ্টতই এটি কেবলমাত্র একটি ভাল ধারণা যদি আপনি এক্স-সেন্ডফিল বা কার্নেলটি ফাইলটি প্রেরণের জন্য এর কোনও রূপ ব্যবহার করতে না পারেন। আপনার উপরের phof () / fread () লুপটি [ php.net/manual/en/function.eio-sendfile.php +( পিএইচপি এর eio_sendfile ()] কল দিয়ে প্রতিস্থাপন করতে সক্ষম হওয়া উচিত যা পিএইচপি তে একই জিনিসটি সম্পাদন করে। এটি সরাসরি কার্নেলে এটি করার মতো দ্রুত নয়, পিএইচপি-তে উত্পাদিত যে কোনও আউটপুট এখনও ওয়েবসার্ভার প্রক্রিয়াটির মধ্য দিয়ে ফিরে যেতে হবে, তবে এটি পিএইচপি কোডের চেয়ে আরও দ্রুত গতিতে পরিণত হবে
ব্রায়ান সি

@ ব্রায়ানসি: অবশ্যই, তবে আপনি এক্স-সেন্ডফাইলে (যা উপলভ্য নাও হতে পারে) গতি বা মাল্টিপার্ট ক্ষমতা সীমাবদ্ধ করতে পারবেন না এবং eioসর্বদা উপলব্ধও হয় না। তবুও, +1, সেই পেকল এক্সটেনশান সম্পর্কে জানত না। =)
অ্যালিক্স অ্যাক্সেল

ট্রান্সফার-এনকোডিং সমর্থন করা কি কার্যকর হবে: খণ্ডিত এবং সামগ্রী-এনকোডিং: জিপ?
skibulk

কেন $size = sprintf('%u', filesize($path))?
সুইভিশ

14
header('Location: ' . $path);
exit(0);

আপাচি আপনার জন্য কাজটি করতে দিন।


12
এটি এক্স-সেন্ডফাইল পদ্ধতির চেয়ে সহজ, তবে কোনও ফাইলের অ্যাক্সেসকে সীমাবদ্ধ করতে কাজ করবে না, কেবলমাত্র লগইন করা লোকেদের বলে। যদি আপনার এটি করার দরকার না হয় তবে এটি দুর্দান্ত!
জর্ডস

মোড_উইরাইট সহ একটি রেফারার চেক যুক্ত করুন।
সনমাই

4
হেডারটি পাস করার আগে আপনি লেখতে পারেন। এইভাবে আপনি পিএইচপি এর স্মৃতিতে টন স্ট্যাম্প পাম্প করছেন না।
ব্রেন্ট

7
@ অলিটিমব্রেন্ট লোকেশনটি এখনও সবার কাছে অ্যাক্সেসযোগ্য হতে হবে .. এবং ক্লায়েন্টের কাছ থেকে আসে বলে রেফারেন্স চেকের কোনও সুরক্ষা নেই
vউইভিন্ড স্কার

@ জিম্বো একজন ব্যবহারকারী টোকেন যে আপনি কীভাবে যাচ্ছেন তা পরীক্ষা করতে যাচ্ছেন? পিএইচপি দিয়ে? হঠাৎ আপনার সমাধান পুনরাবৃত্তি হচ্ছে।
মার্ক আমেরিকা

1

ক্যাশে সমর্থন, কাস্টমাইজড http শিরোনাম সহ একটি আরও ভাল বাস্তবায়ন।

serveStaticFile($fn, array(
        'headers'=>array(
            'Content-Type' => 'image/x-icon',
            'Cache-Control' =>  'public, max-age=604800',
            'Expires' => gmdate("D, d M Y H:i:s", time() + 30 * 86400) . " GMT",
        )
    ));

function serveStaticFile($path, $options = array()) {
    $path = realpath($path);
    if (is_file($path)) {
        if(session_id())
            session_write_close();

        header_remove();
        set_time_limit(0);
        $size = filesize($path);
        $lastModifiedTime = filemtime($path);
        $fp = @fopen($path, 'rb');
        $range = array(0, $size - 1);

        header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $lastModifiedTime)." GMT");
        if (( ! empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModifiedTime ) ) {
            header("HTTP/1.1 304 Not Modified", true, 304);
            return true;
        }

        if (isset($_SERVER['HTTP_RANGE'])) {
            //$valid = preg_match('^bytes=\d*-\d*(,\d*-\d*)*$', $_SERVER['HTTP_RANGE']);
            if(substr($_SERVER['HTTP_RANGE'], 0, 6) != 'bytes=') {
                header('HTTP/1.1 416 Requested Range Not Satisfiable', true, 416);
                header('Content-Range: bytes */' . $size); // Required in 416.
                return false;
            }

            $ranges = explode(',', substr($_SERVER['HTTP_RANGE'], 6));
            $range = explode('-', $ranges[0]); // to do: only support the first range now.

            if ($range[0] === '') $range[0] = 0;
            if ($range[1] === '') $range[1] = $size - 1;

            if (($range[0] >= 0) && ($range[1] <= $size - 1) && ($range[0] <= $range[1])) {
                header('HTTP/1.1 206 Partial Content', true, 206);
                header('Content-Range: bytes ' . sprintf('%u-%u/%u', $range[0], $range[1], $size));
            }
            else {
                header('HTTP/1.1 416 Requested Range Not Satisfiable', true, 416);
                header('Content-Range: bytes */' . $size);
                return false;
            }
        }

        $contentLength = $range[1] - $range[0] + 1;

        //header('Content-Disposition: attachment; filename="xxxxx"');
        $headers = array(
            'Accept-Ranges' => 'bytes',
            'Content-Length' => $contentLength,
            'Content-Type' => 'application/octet-stream',
        );

        if(!empty($options['headers'])) {
            $headers = array_merge($headers, $options['headers']);
        }
        foreach($headers as $k=>$v) {
            header("$k: $v", true);
        }

        if ($range[0] > 0) {
            fseek($fp, $range[0]);
        }
        $sentSize = 0;
        while (!feof($fp) && (connection_status() === CONNECTION_NORMAL)) {
            $readingSize = $contentLength - $sentSize;
            $readingSize = min($readingSize, 512 * 1024);
            if($readingSize <= 0) break;

            $data = fread($fp, $readingSize);
            if(!$data) break;
            $sentSize += strlen($data);
            echo $data;
            flush();
        }

        fclose($fp);
        return true;
    }
    else {
        header('HTTP/1.1 404 Not Found', true, 404);
        return false;
    }
}

0

আপনার যদি পিএইচএল এক্সটেনশনগুলি আপনার পিএইচপি তে যুক্ত করার সম্ভাবনা থাকে তবে আপনি কেবল বিষয়বস্তুর ধরণ নির্ধারণ করতে ফাইলইনফো প্যাকেজ থেকে ফাংশনগুলি ব্যবহার করতে পারেন এবং তারপরে যথাযথ শিরোনাম প্রেরণ করতে পারেন ...


/ গোঁফ, আপনি কি এই সম্ভাবনার কথা উল্লেখ করেছেন? :)
আন্দ্রে লিন্ডেন

0

Downloadএখানে উল্লিখিত পিএইচপি ফাংশনটি ফাইলটি ডাউনলোড শুরু করার আগে কিছুটা বিলম্ব ঘটায়। আমি জানি না এটি কোনও বার্নিশ ক্যাশে ব্যবহার করে বা কী কারণে হয়েছিল, তবে আমার জন্য এটি sleep(1);সম্পূর্ণরূপে সরিয়ে এবং সেট $speedকরতে সহায়তা করেছিল 1024। এখন এটি কোনও সমস্যা ছাড়াই কাজ করে যা নরকের মতো দ্রুত। হতে পারে আপনি সেই ফাংশনটিও সংশোধন করতে পারেন, কারণ আমি দেখেছি এটি ইন্টারনেটে ব্যবহৃত হয়েছে।


0

পিএইচপি এবং স্বয়ংক্রিয় এমআইএমআই টাইপ সনাক্তকরণের সাথে ফাইলগুলি পরিবেশন করার জন্য আমি একটি খুব সাধারণ ক্রিয়াকলাপ কোড করেছি:

function serve_file($filepath, $new_filename=null) {
    $filename = basename($filepath);
    if (!$new_filename) {
        $new_filename = $filename;
    }
    $mime_type = mime_content_type($filepath);
    header('Content-type: '.$mime_type);
    header('Content-Disposition: attachment; filename="downloaded.pdf"');
    readfile($filepath);
}

ব্যবহার

serve_file("/no_apache/invoice243.pdf");
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.