Tag Archives: PHP

PHP: Stream a file line-by-line using a generator

This function will “stream” a file line-by-line, as a Generator.

Can be very useful if for example you need to process a big file, don’t want to read the whole thing into memory, but only process each line by itself.

function read($file)
{
    $fp = fopen($file, 'rb');

    while(($line = fgets($fp)) !== false)
        yield rtrim($line, "\r\n");

    fclose($fp);
}

// Usage
foreach(read('http://example.com') as $line)
{
    var_dump($line);
}

PHP: Delete directory recursively

function delete_directory($dir)
{
    if( ! file_exists($dir))
        return;

    $it = new RecursiveDirectoryIterator($dir);
    $it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);

    foreach($it as $file)
        if($file->isDir())
            @rmdir($file->getRealPath());
        else
            @unlink($file->getRealPath());
}

PHP test script for cross origin proxy target

Just a script I used as target during some testing of a cross origin proxy to make sure whatever I thought should go through actually went through.

<?php // test.php
$info = [
    'method' => $_SERVER['REQUEST_METHOD'],
    'cookie' => $_COOKIE,
    'get' => $_GET,
    'post' => $_POST,
    'input' => file_get_contents('php://input'),
    'headers' => getallheaders(),
];

ob_start('ob_gzhandler');
header('Content-Type: application/json; charset=utf-8');
header('X-SomeHeader: Some value');
echo json_encode($info, JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK | JSON_FORCE_OBJECT);

PHP: Easy Javascript compression with closure compiler

Here’s how to fairly easily compress/minify Javascript by using the Closure Compiler Service API.

More or less verbatim how I’m currently doing it over at bibelstudiet.no in my script controller class, and so far it’s been working great. Just remember to cache the result on your server so that you’re not calling the API more than necessary. In my case it’s handled further up the chain by the parent class 🙂

<?php
ob_start('ob_gzhandler');
header('Content-Type: text/javascript; charset=utf-8');

$files = ['foo.js', 'bar.js'];

$js = array_map('file_get_contents', $files);
$js = implode(PHP_EOL.PHP_EOL, $script);

$c = curl_init();
curl_setopt_array($ch, array
(
    CURLOPT_URL => 'https://closure-compiler.appspot.com/compile',
    CURLOPT_POST => TRUE,
    CURLOPT_POSTFIELDS => http_build_query([
        'language' => 'ECMASCRIPT5',
        'output_info' => 'compiled_code',
        'output_format' => 'text',
        'compilation_level' => 'SIMPLE_OPTIMIZATIONS',
        'js_code' => $js,
    ]),
));

if(curl_exec($ch) === FALSE)
    http_response_code(500) and exit("// ERROR: ".curl_error($c));

if(curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD ) <= 1)
    echo $js;

curl_close($ch);

Note that if the compilation fails for any reason, the response will be empty. In that case I’ve chosen to output the original Javascript instead so the site doesn’t suddenly break. To check what went wrong, you need to repeat the request, but output_info set to errors instead of inline=”true”>compiled_code.

See their API documentation for more information about the parameters.

PHP: Array key whitelist and blacklist

Keep forgetting… writing it down so I can stop googling it…

function whitelist(array $array, array $whitelist)
{
    return array_intersect_key($array, array_flip($whitelist));
}

$filtered = whitelist($array, ['good1', 'good2', ... ]);
function blacklist(array $array, array $blacklist)
{
    return array_diff_key($array, array_flip($blacklist));
}

$filtered = blacklist($array, ['bad1', 'bad2', ...]);

PHP: Authorization header missing on Apache

I’m using a simple PHP cross-domain-proxy to be able to do some Javascript requests towards an API on a different domain. Worked great, until I needed to do basic authentication. I set the appropriate header to be passed through, 'Authorization': 'Basic ' + btoa(username+':'+password), but in the proxy script, that header had vanished.

Turns out it was Apache stripping it away. Don’t know if it’s because of security or because Apache thinks that, hey, I’m the one dealing with this stuff so no point sending it to the script. Anyways, seems you can get it back by doing the following in an .htaccess file:

RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

Now the header is passed through to the API successfully and I’m no longer getting 401 Unauthorized back 🙂