How to exclude image extension from string place in PHP - php

I want to replace all the string values from example.com to sample.com excluding the image extension .png, .jpeg, .jpg etc.
$body = ' www.example.com, example.com, example.com/hello.html, example.com/logo.png, example.com/yourbaby.php , example.com/newimage.jpg, www.example.com/newimage.jpg';
//values
$oldomain = ['example.com','www.'];
$newdomain= ['sample.com', ''];
$excludeextension = [".png", ".jpg", ".jpeg"];
//Replace
$body = str_replace($olddomain, $newdomain, $body);
$body = str_replace($excludeextension, '', $body);
//output
echo $body;
Output i am looking for :
sample.com, sample.com, sample.com/hello.html, example.com/logo.png, sample.com/yourbaby.php , example.com/newimage.jpg, www.example.com/newimage.jpg
Expectation
https://example.com -> https://sample.com
https://www.example.com -> https://sample.com
https://subdomain.example.com -> https://subdomain.sample.com
https://www.example.com/image.png -> https://www.example.com/image.png
https://example.com/image.png -> https://example.com/image.png

You can do this using str_replace() and a bit of exploding and imploding.
$body = ' www.example.com, example.com, example.com/hello.html, example.com/logo.png, example.com/yourbaby.php, example.com/newimage.jpg, www.example.com/newimage.jpg';
$oldomain = ['example.com','www.'];
$newdomain= ['sample.com', ''];
$excludeextension = ["png", "jpg", "jpeg"];
$doms = explode(',', $body);
foreach ($doms as &$dom) {
// get extension
$pi = pathinfo($dom);
if ( ! in_array( $pi['extension'], $excludeextension) ){
$dom = str_replace($oldomain, $newdomain, $dom);
}
}
$NewStr = implode($doms);
echo $NewStr;
RESULT
sample.com sample.com sample.com/hello.html example.com/logo.png sample.com/yourbaby.php example.com/newimage.jpg www.example.com/newimage.jpg

Using PATHINFO_EXTENSION & str_replace
First explode than implode
$body = 'example.com, www.example.com, https://www.example.com, https://example.com, subdomain.example.com, example.com/logo.png, www.example.com/logo.png, example.com/hello/logo.png, https://example.com/logo.png, subdomain.example.com/logo.png"';
//Defined Values
$oldomain = ["example.com", "www.example.com"];
$newdomain = "sample.com";
$excludeextension = ["png", "jpg", "jpeg", "css"];
// Split the string into an array of URLs
$urls_body_extension = explode(", ", $body);
// Loop through each URL and replace it if necessary
foreach ($urls_body_extension as &$url_body_extension) {
$extension_body_extension = pathinfo($url_body_extension, PATHINFO_EXTENSION);
if (!in_array($extension_body_extension, $excludeextension)) {
foreach ($oldomain as $domain_body_extension) {
if (strpos($url_body_extension, $domain_body_extension) !== false) {
$url_body_extension = str_replace($domain_body_extension, $newdomain, $url_body_extension);
break;
}
}
}
}
// Join the modified URLs back into a string
$body = implode(", ", $urls_body_extension);
echo $body;

Related

IMAP PHP with embedded images not showing Codeigniter on localhost

I use codeigniter and imap php currently developing project xampp. For some reason them embedded images not showing.
In my getBody() function I have this call back
$body = preg_replace_callback(
'/src="cid:(.*)">/Uims',
function($m) use($email, $uid){
//split on #
$parts = explode('#', $m[1]);
//replace local path with absolute path
$img = str_replace($parts[0], '', $parts[0]);
return "src='$img'>";
},
$body);
I get error
Question: How can I make sure it gets the images correct for the text/html body etc.
<?php
class Email extends MY_Controller {
private $enc;
private $host;
private $user;
private $pass;
private $mailbox;
private $mbox;
public function __construct() {
parent::__construct();
$this->enc = '/imap/ssl/novalidate-cert';
$this->host = '****';
$this->user = '****'; // email
$this->pass = '****'; // Pass
$this->mailbox = '{' . $this->host . $this->enc . '}';
$this->mbox = imap_open($this->mailbox, $this->user, $this->pass);
}
public function view() {
$this->data['message'] = $this->getBody($this->uri->segment(4));
$this->load->view('template/common/header', $this->data);
$this->load->view('template/common/nav', $this->data);
$this->load->view('template/mail/view', $this->data);
$this->load->view('template/common/footer', $this->data);
imap_close($this->mbox);
}
public function getBody($uid) {
$body = $this->get_part($uid, "TEXT/HTML");
// if HTML body is empty, try getting text body
if ($body == "") {
$body = $this->get_part($uid, "TEXT/PLAIN");
}
$email = $this->user;
//replace cid with full path to image
$body = preg_replace_callback(
'/src="cid:(.*)">/Uims',
function($m) use($email, $uid){
//split on #
$parts = explode('#', $m[1]);
//replace local path with absolute path
$img = str_replace($parts[0], '', $parts[0]);
return "src='$img'>";
},
$body);
return trim(utf8_encode(quoted_printable_decode($body)));
}
private function get_part($uid, $mimetype, $structure = false, $partNumber = false) {
if (!$structure) {
$structure = imap_fetchstructure($this->mbox, $uid);
}
if ($structure) {
if ($mimetype == $this->get_mime_type($structure)) {
if (!$partNumber) {
$partNumber = 1;
}
$text = imap_fetchbody($this->mbox, $uid, $partNumber, FT_PEEK);
switch ($structure->encoding) {
# 7BIT
case 0:
return imap_qprint($text);
# 8BIT
case 1:
return imap_8bit($text);
# BINARY
case 2:
return imap_binary($text);
# BASE64
case 3:
return imap_base64($text);
# QUOTED-PRINTABLE
case 4:
return quoted_printable_decode($text);
# OTHER
case 5:
return $text;
# UNKNOWN
default:
return $text;
}
}
// multipart
if ($structure->type == 1) {
foreach ($structure->parts as $index => $subStruct) {
$prefix = "";
if ($partNumber) {
$prefix = $partNumber . ".";
}
$data = $this->get_part($uid, $mimetype, $subStruct, $prefix . ($index + 1));
if ($data) {
return $data;
}
}
}
}
return false;
}
private function get_mime_type($structure) {
$primaryMimetype = array("TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER");
if ($structure->subtype) {
return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype;
}
return "TEXT/PLAIN";
}
}
Introduction
You are trying to convert an Email into a HTML Page.
An Email has multiple parts:
Headers
Text based email
HTML based email
Attachments
In the header you will find the Message-ID as well as other relevant metadata.
In order to convert an Email into a website you have to expose the HTML and the Attachments to the browser.
Each of the Parts has its own headers. When you have a url='cid:Whatever' you have to look for which part of the email hast that Content-Id header.
Serve the Email as a Web Page
You need to find wich Email part contains the HTML Body. Parse it and replace the CID URL's for your http://yourhost/{emailId} you already implemented that part so I will not add how to do it here.
Replace CID URL on HTML - Implementation
This is a prototype that may work for you.
$mailHTML="<html>All your long code here</html>";
$mailId="email.eml";
$generatePartURL=function ($messgeId, $cid) {
return "http://myhost/".$messgeId."/".$cid; //Adapt this url according to your needs
};
$replace=function ($matches) use ($generatePartURL, $mailId) {
list($uri, $cid) = $matches;
return $generatePartURL($mailId, $cid);
};
$mailHTML=preg_replace_callback("/cid:([^'\" \]]*)/", $replace, $mailHTML);
Find the part by CID
http://yourhost/{emailId}/{cid}
Pseudo code:
Load email
Find part by CID
Decode from Base64 or other Encoding used (Check Content-Transfer-Encoding header)
Serve the file as an HTTP Response
Which part has my CID image?
Iterate all email parts looking for the Content-ID header that match your CID value.
--_part_boundery_
Content-Type: image/jpeg; name="filename.jpg"
Content-Description: filename.jpg
Content-Disposition: inline; filename="filename.jpg"; size=39619; creation-date="Thu, 28 Dec 2017 10:53:51 GMT"; modification-date="Thu, 28 Dec 2017 10:53:51 GMT"
Content-ID: <YOUR CID WILL BE HERE>
Content-Transfer-Encoding: base64
Decode the transfer encoding and serve the contents as a regular http file.
Webmail implemented in PHP
RoundCube is a webmail implemented in PHP you can have a look how they do this: https://github.com/roundcube/roundcubemail/blob/master/program/lib/Roundcube/rcube_washtml.php
Note: My code it is not based in this solution.

Using Zend_Http_Client to send json POST

I'm trying to send a json object as a POST command using the following:
$uri = "http://amore-luce.com/product_create";
$product = $observer->getEvent()->getProduct();
$json = Mage::helper('core')->jsonEncode($product);
Mage::log(" Json={$json}", null,'product-updates.txt');
// new HTTP request to some HTTP address
$client = new Zend_Http_Client('http://amore-luce.com/product_create');
// set some parameters
$client->setParameterPost('product', $json);
// POST request
$response = $client->request(Zend_Http_Client::POST);
When I view the $json the data is there and all looks good - however the POST is not sending the json data. I'm capturing it using a simple email form that should send me the response:
<?php
$webhookContent = "";
$ref = "";
$webhook = fopen('php://input' , 'rb');
while (!feof($webhook)) {
$webhookContent .= fread($webhook, 4096);
}
fclose($webhook);
$headers = array();
foreach($_SERVER as $key => $value) {
if (substr($key, 0, 5) <> 'HTTP_') {
continue;
}
$header = str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))));
$headers[$header] = $value;
}
foreach ($headers as $header => $value) {
$ref .= "$header: $value <br />\n";
}
$post = file_get_contents('php://input');
$to = "address#my-email.com"; //the address the email is being sent to
$subject = "This is the subject"; //the subject of the message
$msg = "This is the message - Webhook content: ".$webhookContent." This is url: ".$ref; //the message of the email
mail($to, $subject, $msg, 'From: PHP Scriptv2 <noreply#domain.com>'); //send the email.
echo ($_SERVER['HTTP_REFERER']."<br>".$_SERVER['REQUEST_URI']);
?>
This page works with other json POST requests I've sent to it. I'm fairly new at sending POST requests so any help would be greatly appreciated.
Try change :
$client->setParameterPost('product', $json);
to :
$client->setHeaders('Content-type','application/json');
$client->setParameterPost('product', $json);
or use:
$client->setRawData($json, 'application/json');
So Update / Answer changing how I did it to these lines of code:
$uri = "http://requestb.in/p6p4syp6";
$product = $observer->getEvent()->getProduct();
$json = Mage::helper('core')->jsonEncode($product);
Mage::log(" Json={$json}", null,'product-updates.txt');
$client = new Zend_Http_Client($uri);
$client->setRawData($json, null)->request('POST');
Changing the SetRawData($json, null) was the bit - using SetRawDate($json, 'application/json') caused it to fail.
Thanks Voodoo417 - I'll also try your suggestion and see if that lets me set the correct type

PHP file_get_contents then replace string in a function

**User_Tpl.html**
<html><head></head>
<body>
Hello {NAME},
Business name : {BUSINESS_NAME}.
Tel : {TELEPHONE}.
Mob : {MOBILE}.
</body>
</html>
function mailFooter($content) {
$sBusiness = 'Business name';
$sTelp = '0';
$sMobile = '0';
$content = str_replace('{BUSINESS_NAME}', $sBusiness, $content);
$content = str_replace('{TELEPHONE}', $sTelp, $content);
$content = str_replace('{MOBILE}', $sMobile, $content);
return $content;
}
$content = file_get_contents('page/email/User_Tpl.html');
$content = str_replace('{SUBJECT}', $subject, $content);
$content = str_replace('{NAME}', $ownerName, $content);
**mailerFooter($content);**
// always return {BUSINESS_NAME}, {TELEPHONE}
$mail->AddAddress( $email );
$mail->SetFrom($name );
$mail->AddReplyTo( $reply );
$mail->Subject = trim($subject);
$mail->MsgHTML( trim($content) );
$mail->IsHTML(true);
$mail->Send();
im using PHPMailer as Mailer library and how to replace those {strings} inside the mailFooter() function.
use array
$content ='
<html><head></head>
<body>
Hello {NAME},
Business name : {BUSINESS_NAME}.
Tel : {TELEPHONE}.
Mob : {MOBILE}.
</body>
</html>';
$search= array ('{BUSINESS_NAME}','{TELEPHONE}','{MOBILE}');
$replace=array($sBusiness,$sTelp,$sMobile);
$content =str_replace($search,$replace,$content);
private arr = array(
"{title}" => "Home page",
"{email}" => "my#mail.com",
...
);
private $content = "Title for my site - {title}, if you interesting my email addres -> {email}"
$this->content = strtr($this->content, $this->arr);
echo $this->content;
This return -> "Title for my site - Home page, if you interesting my email addres -> my#mail.com"

check string for youtube link or image

I have a small piece of code that checks a string for a url and adds the < a href> tag to create a link. I also have it check the string for a youtube link and then add rel="youtube" to the < a> tag.
How can I get the code to only add rel to the youtube links?
How can I get it to add a different rel to any type of image link?
$text = "http://site.com a site www.anothersite.com/ http://www.youtube.com/watch?v=UyxqmghxS6M here is another site";
$linkstring = preg_replace( '/(http|ftp)+(s)?:(\/\/)((\w|\.)+)(\/)?(\S+)?/i', '\4', $text );
if(preg_match('/http:\/\/www\.youtube\.com\/watch\?v=[^&]+/', $linkstring, $vresult)) {
$linkstring = preg_replace( '/(http|ftp)+(s)?:(\/\/)((\w|\.)+)(\/)?(\S+)?/i', '<a rel="youtube" href="\0">\4</a>', $text );
$type= 'youtube';
}
else {
$type = 'none';
}
echo $text;
echo $linkstring, "<br />";
echo $type, "<br />";
Try http://simplehtmldom.sourceforge.net/.
Code:
<?php
include('simple_html_dom.php');
$html = str_get_html('Link');
$html->find('a', 0)->rel = 'youtube';
echo $html;
Output:
[username#localhost dom]$ php dom.php
Link
You can build an entire page DOM or a simple single link with this library.
Detecting hostname of URL:
Pass the url to parse_url. parse_url returns an array of the URL parts.
Code:
print_r(parse_url('http://www.youtube.com/watch?v=UyxqmghxS6M'));
Output:
Array
(
[scheme] => http
[host] => www.youtube.com
[path] => /watch
[query] => v=UyxqmghxS6M
)
Try the following:
//text
$text = "http://site.com/bounty.png a site www.anothersite.com/ http://www.youtube.com/watch?v=UyxqmghxS6M&featured=true here is another site";
//Youtube links
$pattern = "/(http:\/\/){0,1}(www\.){0,1}youtube\.com\/watch\?v=([a-z0-9\-_\|]{11})[^\s]*/i";
$replacement = '<a rel="youtube" href="http://www.youtube.com/watch?v=\3">\0</a>';
$text = preg_replace($pattern, $replacement, $text);
//image links
$pattern = "/(http:\/\/){0,1}(www\.){0,1}[^\/]+\/[^\s]+\.(png|jpg|jpeg|bmp|gif)[^\s]*/i";
$replacement = '<a rel="image" href="\0">\0</a>';
$text = preg_replace($pattern, $replacement, $text);
note that the latter can only detect links to images which have an extension. As such, links like www.example.com?image=3 will not be detected.

PHP multipart form data PUT request?

I'm writing a RESTful API. I'm having trouble with uploading images using the different verbs.
Consider:
I have an object which can be created/modified/deleted/viewed via a post/put/delete/get request to a URL. The request is multi part form when there is a file to upload, or application/xml when there's just text to process.
To handle the image uploads which are associated with the object I am doing something like:
if(isset($_FILES['userfile'])) {
$data = $this->image_model->upload_image();
if($data['error']){
$this->response(array('error' => $error['error']));
}
$xml_data = (array)simplexml_load_string( urldecode($_POST['xml']) );
$object = (array)$xml_data['object'];
} else {
$object = $this->body('object');
}
The major problem here is when trying to handle a put request, obviously $_POST doesn't contain the put data (as far as I can tell!).
For reference this is how I'm building the requests:
curl -F userfile=#./image.png -F xml="<xml><object>stuff to edit</object></xml>"
http://example.com/object -X PUT
Does anyone have any ideas how I can access the xml variable in my PUT request?
First of all, $_FILES is not populated when handling PUT requests. It is only populated by PHP when handling POST requests.
You need to parse it manually. That goes for "regular" fields as well:
// Fetch content and determine boundary
$raw_data = file_get_contents('php://input');
$boundary = substr($raw_data, 0, strpos($raw_data, "\r\n"));
// Fetch each part
$parts = array_slice(explode($boundary, $raw_data), 1);
$data = array();
foreach ($parts as $part) {
// If this is the last part, break
if ($part == "--\r\n") break;
// Separate content from headers
$part = ltrim($part, "\r\n");
list($raw_headers, $body) = explode("\r\n\r\n", $part, 2);
// Parse the headers list
$raw_headers = explode("\r\n", $raw_headers);
$headers = array();
foreach ($raw_headers as $header) {
list($name, $value) = explode(':', $header);
$headers[strtolower($name)] = ltrim($value, ' ');
}
// Parse the Content-Disposition to get the field name, etc.
if (isset($headers['content-disposition'])) {
$filename = null;
preg_match(
'/^(.+); *name="([^"]+)"(; *filename="([^"]+)")?/',
$headers['content-disposition'],
$matches
);
list(, $type, $name) = $matches;
isset($matches[4]) and $filename = $matches[4];
// handle your fields here
switch ($name) {
// this is a file upload
case 'userfile':
file_put_contents($filename, $body);
break;
// default for all other files is to populate $data
default:
$data[$name] = substr($body, 0, strlen($body) - 2);
break;
}
}
}
At each iteration, the $data array will be populated with your parameters, and the $headers array will be populated with the headers for each part (e.g.: Content-Type, etc.), and $filename will contain the original filename, if supplied in the request and is applicable to the field.
Take note the above will only work for multipart content types. Make sure to check the request Content-Type header before using the above to parse the body.
Please don't delete this again, it's helpful to a majority of people coming here! All previous answers were partial answers that don't cover the solution as a majority of people asking this question would want.
This takes what has been said above and additionally handles multiple file uploads and places them in $_FILES as someone would expect. To get this to work, you have to add 'Script PUT /put.php' to your Virtual Host for the project per Documentation. I also suspect I'll have to setup a cron to cleanup any '.tmp' files.
private function _parsePut( )
{
global $_PUT;
/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");
/* Open a file for writing */
// $fp = fopen("myputfile.ext", "w");
$raw_data = '';
/* Read the data 1 KB at a time
and write to the file */
while ($chunk = fread($putdata, 1024))
$raw_data .= $chunk;
/* Close the streams */
fclose($putdata);
// Fetch content and determine boundary
$boundary = substr($raw_data, 0, strpos($raw_data, "\r\n"));
if(empty($boundary)){
parse_str($raw_data,$data);
$GLOBALS[ '_PUT' ] = $data;
return;
}
// Fetch each part
$parts = array_slice(explode($boundary, $raw_data), 1);
$data = array();
foreach ($parts as $part) {
// If this is the last part, break
if ($part == "--\r\n") break;
// Separate content from headers
$part = ltrim($part, "\r\n");
list($raw_headers, $body) = explode("\r\n\r\n", $part, 2);
// Parse the headers list
$raw_headers = explode("\r\n", $raw_headers);
$headers = array();
foreach ($raw_headers as $header) {
list($name, $value) = explode(':', $header);
$headers[strtolower($name)] = ltrim($value, ' ');
}
// Parse the Content-Disposition to get the field name, etc.
if (isset($headers['content-disposition'])) {
$filename = null;
$tmp_name = null;
preg_match(
'/^(.+); *name="([^"]+)"(; *filename="([^"]+)")?/',
$headers['content-disposition'],
$matches
);
list(, $type, $name) = $matches;
//Parse File
if( isset($matches[4]) )
{
//if labeled the same as previous, skip
if( isset( $_FILES[ $matches[ 2 ] ] ) )
{
continue;
}
//get filename
$filename = $matches[4];
//get tmp name
$filename_parts = pathinfo( $filename );
$tmp_name = tempnam( ini_get('upload_tmp_dir'), $filename_parts['filename']);
//populate $_FILES with information, size may be off in multibyte situation
$_FILES[ $matches[ 2 ] ] = array(
'error'=>0,
'name'=>$filename,
'tmp_name'=>$tmp_name,
'size'=>strlen( $body ),
'type'=>$value
);
//place in temporary directory
file_put_contents($tmp_name, $body);
}
//Parse Field
else
{
$data[$name] = substr($body, 0, strlen($body) - 2);
}
}
}
$GLOBALS[ '_PUT' ] = $data;
return;
}
For whom using Apiato (Laravel) framework:
create new Middleware like file below, then declair this file in your laravel kernel file within the protected $middlewareGroups variable (inside web or api, whatever you want) like this:
protected $middlewareGroups = [
'web' => [],
'api' => [HandlePutFormData::class],
];
<?php
namespace App\Ship\Middlewares\Http;
use Closure;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
* #author Quang Pham
*/
class HandlePutFormData
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
*
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($request->method() == 'POST' or $request->method() == 'GET') {
return $next($request);
}
if (preg_match('/multipart\/form-data/', $request->headers->get('Content-Type')) or
preg_match('/multipart\/form-data/', $request->headers->get('content-type'))) {
$parameters = $this->decode();
$request->merge($parameters['inputs']);
$request->files->add($parameters['files']);
}
return $next($request);
}
public function decode()
{
$files = [];
$data = [];
// Fetch content and determine boundary
$rawData = file_get_contents('php://input');
$boundary = substr($rawData, 0, strpos($rawData, "\r\n"));
// Fetch and process each part
$parts = $rawData ? array_slice(explode($boundary, $rawData), 1) : [];
foreach ($parts as $part) {
// If this is the last part, break
if ($part == "--\r\n") {
break;
}
// Separate content from headers
$part = ltrim($part, "\r\n");
list($rawHeaders, $content) = explode("\r\n\r\n", $part, 2);
$content = substr($content, 0, strlen($content) - 2);
// Parse the headers list
$rawHeaders = explode("\r\n", $rawHeaders);
$headers = array();
foreach ($rawHeaders as $header) {
list($name, $value) = explode(':', $header);
$headers[strtolower($name)] = ltrim($value, ' ');
}
// Parse the Content-Disposition to get the field name, etc.
if (isset($headers['content-disposition'])) {
$filename = null;
preg_match(
'/^form-data; *name="([^"]+)"(; *filename="([^"]+)")?/',
$headers['content-disposition'],
$matches
);
$fieldName = $matches[1];
$fileName = (isset($matches[3]) ? $matches[3] : null);
// If we have a file, save it. Otherwise, save the data.
if ($fileName !== null) {
$localFileName = tempnam(sys_get_temp_dir(), 'sfy');
file_put_contents($localFileName, $content);
$files = $this->transformData($files, $fieldName, [
'name' => $fileName,
'type' => $headers['content-type'],
'tmp_name' => $localFileName,
'error' => 0,
'size' => filesize($localFileName)
]);
// register a shutdown function to cleanup the temporary file
register_shutdown_function(function () use ($localFileName) {
unlink($localFileName);
});
} else {
$data = $this->transformData($data, $fieldName, $content);
}
}
}
$fields = new ParameterBag($data);
return ["inputs" => $fields->all(), "files" => $files];
}
private function transformData($data, $name, $value)
{
$isArray = strpos($name, '[]');
if ($isArray && (($isArray + 2) == strlen($name))) {
$name = str_replace('[]', '', $name);
$data[$name][]= $value;
} else {
$data[$name] = $value;
}
return $data;
}
}
Pls note: Those codes above not all mine, some from above comment, some modified by me.
Quoting netcoder reply : "Take note the above will only work for multipart content types"
To work with any content type I have added the following lines to Mr. netcoder's solution :
// Fetch content and determine boundary
$raw_data = file_get_contents('php://input');
$boundary = substr($raw_data, 0, strpos($raw_data, "\r\n"));
/*...... My edit --------- */
if(empty($boundary)){
parse_str($raw_data,$data);
return $data;
}
/* ........... My edit ends ......... */
// Fetch each part
$parts = array_slice(explode($boundary, $raw_data), 1);
$data = array();
............
...............
I've been trying to figure out how to work with this issue without having to break RESTful convention and boy howdie, what a rabbit hole, let me tell you.
I'm adding this anywhere I can find in the hope that it will help somebody out in the future.
I've just lost a day of development firstly figuring out that this was an issue, then figuring out where the issue lay.
As mentioned, this isn't a symfony (or laravel, or any other framework) issue, it's a limitation of PHP.
After trawling through a good few RFCs for php core, the core development team seem somewhat resistant to implementing anything to do with modernising the handling of HTTP requests. The issue was first reported in 2011, it doesn't look any closer to having a native solution.
That said, I managed to find this PECL extension called Always Populate Form Data. I'm not really very familiar with pecl, and couldn't seem to get it working using pear. but I'm using CentOS and Remi PHP which has a yum package.
I ran yum install php-pecl-apfd and it literally fixed the issue straight away (well I had to restart my docker containers but that was a given).
I believe there are other packages in various flavours of linux and I'm sure anybody with more knowledge of pear/pecl/general php extensions could get it running on windows or mac with no issue.
I know this article is old.
But unfortunately, PHP still does not pay attention to form-data other than the Post method.
Thanks to friends (#netcoder, #greendot, #pham-quang) who suggested solutions above.
Using those solutions I wrote a library for this purpose:
composer require alireaza/php-form-data
You can also use composer require alireaza/laravel-form-data in Laravel.

Categories