/** * @link http://tools.ietf.org/html/rfc2046 * @param array $parts ['Content-Disposition'=>['form-data','name'=>'counts'],'value'=>'partcontent'] * @param array $headers ['Content-Type'=>['multipart/form-data','boundary'=>'VeryUniqueBoundary']] * @return array */ function mime_multipart_encode($parts, $headers = array()) { debug_enforce(is_array($parts) && is_array($headers), var_dump_human_compact([$parts, $headers])); $parts_contain = function ($boundary) use($parts) { return array_contains($parts, function ($part) use($boundary) { str_contains($part['value'], $boundary); }); }; if (!array_key_exists('Content-Type', $headers)) { $headers['Content-Type'] = array(); } if (!isset($headers['Content-Type'][0])) { $headers['Content-Type'] = array_merge(array('multipart/form-data'), $headers['Content-Type']); } if (!isset($headers['Content-Type']['boundary']) || $headers['Content-Type']['boundary'] === '""') { $headers['Content-Type']['boundary'] = ''; $empty_header = mime_header_entry_map($headers['Content-Type'], 'Content-Type'); $boundaryCnt = 70 - strlen($empty_header) - 2; // FIXME: including CRLF ? do { $boundary = str_ascii7_prand($boundaryCnt, function ($char) { return ctype_alnum($char) || $char === "'" || $char === "(" || $char === ")" || $char === "+" || $char === "_" || $char === "," || $char === "-" || $char === "." || $char === "/" || $char === ":" || $char === "=" || $char === "?"; }); } while ($parts_contain($boundary)); $headers['Content-Type']['boundary'] = $boundary; } else { $boundary = $headers['Content-Type']['boundary']; } if (array_all($parts, function ($val) { return !(is_array($val) && array_key_exists('value', $val)); })) { $parts = array_map_val($parts, function ($part) { return array('value' => $part); }); } $parts = array_map_val($parts, function ($part) use($boundary) { debug_enforce(array_key_exists('value', $part)); $content = $part['value']; unset($part['value']); $headers = array_map_val($part, 'mime_header_entry_map'); return '--' . $boundary . "\r\n" . implode('', $headers) . "\r\n" . $content . "\r\n"; }); return array(implode('', $parts) . '--' . $boundary . '--', $headers); }
/** * @param int $length * @param bool $special_chars * @param bool $extra_special_chars * * @return string */ function str_random($length = 12, $special_chars = true, $extra_special_chars = false) { $allowed = ctype_alnum_dg(); if (true === $special_chars) { $allowed = or_dg($allowed, ctype_special_dg()); } if (true === $extra_special_chars) { $allowed = or_dg($allowed, ctype_special_extra_dg()); } return str_ascii7_prand($length, $allowed); }
/** * @param string $suffix * @param string $prefix * @param string|null $dir * @param int $tries * @return string path to new (existing) temporary file */ function tempfile_str($suffix = '', $prefix = '', $dir = null, $tries = 5) { if (!debug_assert(is_string($suffix), "Invalid suffix '{$suffix}'")) { $suffix = ''; } if (!debug_assert(is_string($prefix), "Invalid prefix '{$prefix}'")) { $prefix = ''; } if (is_null($dir)) { $dir = sys_get_temp_dir(); } else { if (!debug_assert(is_dir($dir), "Invalid directory '{$dir}'")) { $dir = sys_get_temp_dir(); } } if (!str_endswith($dir, DIRECTORY_SEPARATOR)) { $dir .= DIRECTORY_SEPARATOR; } for ($i = 0; $i < $tries; $i++) { $path = $dir . $prefix . str_ascii7_prand(20, 'ctype_alnum') . $suffix; $handle = @fopen($path, 'xb'); if (false !== $handle) { debug_assert(true === fclose($handle)); return $path; } } debug_enforce(false, "Failed to create temporary file '{$tries}' times in a row."); return false; }