Laravel functions arrays and datamodels - php

I have been working on some old code that was given to me to play with and edit to get familar with and i was wondering if you can see if what i am doing is syntactly sound as im confusing myself with the laravel framework. i basically want to know if im close to what my comments are wanting to do and whether my code and comments marry up or a i missing the point? As im getting the following error message
The error message im getting when running this command through my terminal is
PHP Parse error: syntax error, unexpected '$email' (T_VARIABLE), expecting '(' in /Libraryenter code here/WebServer/Documents/healthandsafetymonitoringsystem.local/app/commands/IncompleteReportsCommand.php on line 157
my code is as follows
// This function uses the parameters $data that is passed to this function each time
// the fire() function loops through and assigns and determines that there is a duereport
private function sendGeneralManagerEmail($data)
{
// create an array called 'Park' that is poulated via the $data parameters
// in the function and is specificly looking for the ParkName entries
$data['Park'] = $Park->ParkName;
//for each item in that array use $ParkName as a key and name each elements $name
foreach($data['Park'] as $ParkName => $name)
{
// Every time i loop through this file get the element $name and
// attach this prefix to it
$email = $name."generalmanager#parkholidays.com";
}
// Then send an email with new $email variable as a reciepient and sending the $data passed
// from the fire() function and used within this functions parameters
Mail::send('emails.GeneralManager', $data, function($message) use $email
{
$message->to( $email, 'General Manager')->subject('[Urgent] Health & Safety Reports');
});
}
Sorry for the dumb question if there are any articles regarding arrays/data models and php functions in laravel that you suggest reading thatll be great. This is a steep learnign curve as i have gone from plain php coding on notepad ++ to laravel 4 and i cant seem to find a nice tutorial that goes from the start to finish with a complete novice in mind.
Regards mike

Regarding your error
You just have a PHP syntax error. Here's the code you want:
// This function uses the parameters $data that is passed to this function each time
// the fire() function loops through and assigns and determines that there is a duereport
private function sendGeneralManagerEmail($data)
{
// create an array called 'Park' that is poulated via the $data parameters
// in the function and is specificly looking for the ParkName entries
$data['Park'] = $Park->ParkName;
//for each item in that array use $ParkName as a key and name each elements $name
foreach($data['Park'] as $ParkName => $name)
{
// Every time i loop through this file get the element $name and
// attach this prefix to it
$email = $name."generalmanager#parkholidays.com";
}
// Then send an email with new $email variable as a reciepient and sending the $data passed
// from the fire() function and used within this functions parameters
Mail::send('emails.GeneralManager', $data, function($message) use ($email)
{
$message->to( $email, 'General Manager')->subject('[Urgent] Health & Safety Reports');
});
}
See the use $email you had that I've changed to use ($email) in the closure at the end.
Regarding your more general question about coding
I can see a few things that don't look right to me. Is this code an exact replica of the function or have you removed some code?

It is hard to say more about you code, since it is taken out of context.
Writing new code as answer, will confuse you more.
So it is better to:
Subscribe to laracast and you will learn everything you need to know about Laravel. Also there is new, updated Laravel 4.1 documentation

Related

Argument value not being passed while creating class object in PHP

I am new to PHP and am facing the below issue. There are two files:
In the first PHP file I am writing the below code to create an object
$oNotas = new gcibjdnf($sFiltro, false,'apcconc.nm_apelido', $bBuscarPorChassi);
In the second file-gcibjdnf.php, I have the below code for the constructor
public function __construct($sFiltro = '', $bPaginar = false, $sOrdem= 'apcconc.nm_apelido, danfe', $bBuscarPorChassi = false) {
...}
However,
when I print $sOrdem from the gcibjdnf.php file, I am getting "apcconc.nm_apelido, danfe" as an output.
According to me it should print "apcconc.nm_apelido". But it is printing the default parameter instead of the value passed.
I am using PHP 5.6 version. Please let me know in case anyone has any idea on this.

Q&A: How to get POST variables with PHP on Alibaba Cloud Function Compute service

I played around with the PHP 7.2 runtime and HTTP trigger on Alibaba Cloud Function Compute. The basic example in the documentation is the following:
<? php
use RingCentral\Psr7\Response;
function handler($request, $context): Response{
/*
$body = $request->getBody()->getContents();
$queries = $request->getQueryParams();
$method = $request->getMethod();
$headers = $request->getHeaders();
$path = $request->getAttribute("path");
$requestURI = $request->getAttribute("requestURI");
$clientIP = $request->getAttribute("clientIP");
*/
return new Response(
200,
array(
"custom_header1" => "v1"
),
"hello world"
);
}
This works quite well. It's easy to get the query parameters from an URL. But the body content is only available in a whole string with
$request->getBody()->getContents();
Although the documentation says that the $request parameter follows the PSR-7 HTTP Message standard, it is not possible to use $request->getParsedBody() to deliver the values submitted by POST method. It didn't work as expected - the result remains empty.
The reason is the underlying technology. Alibaba Cloud Function Compute makes use of the event-driven React PHP library to handle the requests (you can check this by analyzing the $request object). So the $_POST array is empty and there is no "easy way to get POST data".
Luckily, Alibaba's Function Compute handler provides the body content by $request->getBody()->getContents(); as a string like
"bar=lala&foo=bar"
So a solution seems easiser than thought at the beginning, you can e.g. use PHP's own parse_str() function:
$data = [];
$body = $request->getBody()->getContents();
parse_str($body,$data);
If you place this snippet in the handler function, the POST variables are stored in the $data array and ready for further processing.
Hope that this helps somebody who asked the same questions than I. :-)
Kind regards,
Ralf
As you can see in the documentation you need to add a RequestBodyParserMiddleware as middleware to get a parsed PSR-7 request. It seems you didn't do that.
Also keep in mind that only the Content-Types: application/x-www-form-urlencoded and multipart/form-data are supported here. So make sure the client need to send these headers so the request can be parsed. If it's another Content-Type you need to use another middleware.
See: https://github.com/reactphp/http#requestbodyparsermiddleware for more information.
I hope this helps!
#legionth: I apologize that I didn't use the comment feature here, but my answer is too long. :-)
Thanks a lot for your comments - the usage of RequestBodyParserMiddleware is a great solution if you can control the server code. But in the context of Alibaba Cloud Function Compute service this seems not possible. I tried to find out more information about the invocation process - here are my results:
Function Compute makes use of the Docker image defined in https://github.com/aliyun/fc-docker/blob/master/php7.2/run/Dockerfile .
In the build process they download a PHP runtime environment from https://my-fc-testt.oss-cn-shanghai.aliyuncs.com/php7.2.tgz . (I didn't find this on GitHub, but the code is public downloadable.)
A shell script start_server.sh starts a PHP-CGI binary and runs a PHP script server.php.
In server.php a React\Http\Server is started by:
$server = new Server(function (ServerRequestInterface $request) {
[...]
});
[...]
$socket = new \React\Socket\Server(sprintf('0.0.0.0:%s', $port), $loop);
$server->listen($socket);
$loop->run();
As seen in the Function Compute documentation (& example of FC console), I can only use two functions:
/*
if you open the initializer feature, please implement the initializer function, as below:
*/
function initializer($context) {
}
and the handler function you can find in my first post.
Maybe Alibaba will extend the PHP runtime in future to make it possible to use a custom middleware, but currently I didn't find a way to do this.
Thanks again & kind regards,
Ralf

Testing method with no output

I have the following method I want to test:
class SomeObject {
public function actionFromSomeController() {
$obj = new OtherObject();
$obj -> setAttributes();
$obj -> doAction();
}
}
class OtherObject {
private $_attr;
public function setAttributes() {
$this -> _attr = 'something';
Database :: execute('INSERT INTO table VALUES (' . $this -> _attr . ')');
$fileObj = new FileObj();
$content = $fileObj -> getSomeFileContent();
// do something else
}
public function doAction() {
echo $this -> _attr;
}
}
Now I want to test this method, its output depends on database content and one file on the server. It does a lot of things on the way, and the output is just one ID and success => 1.
How should I test it properly?
Some ideas on how to test small code pieces like this:
Generate test-data and pass it to your methods (also, fake database return data or file contents)
Use echo / var_dump() / die() to check property and variable content at different positions in your methods
Also use these commands to check whether execution reaches a certain point (for example to see whether a function got called or not)
If something doesn't work as expected without an error message: Check line by line with the above methods until you find the problem
Consider using interfaces and dependency injection if your code gets bigger - this is a bit over-the-top for this amount of code, but can be a tremendous time-saver when your application becomes big
Testing is never an automatic process and you will always have to think about what makes sense to do and what not. These things to do are never magic but basic PHP.
You should consider letting your scripts throw errors/exceptions if something goes wrong. Writing "silent" applications is almost never good since you can, if you really need a silent execution for production environments, just turn off error reporting and have the same effect. Many PHP functions return something special on failure and/or success and you can check for this. Database handlers do so, too. Do yourself a favor and use these return values!

Writing a subscribe method of RabbitMQ in PHP

I have a function as defined below:
public function subscribe($someQueue)
{
$callback = function($msg){
return $msg->body;
};
$this->channel->basic_consume( $someQueue, '', FALSE, TRUE, FALSE, FALSE, $callback);
while(count($this->channel->callbacks)) {
$this->channel->wait();
}
}
I'm using the following function:
Note: Following lines are in a different class file, hence creating object of the class that contains the above function.
$objRMQ = new RabbitMQ();
$msgBody = $objRMQ->subscribe("someQueue");
echo "message body returned from someMethod: ".$msgBody;
Basically, I want to return body of every message to the caller function that is published to the queue.
Current output:
message body returned from subscribe: NULL
Expected output:
holla, this is your message from queue
Since this question is old but still unanswered, I'll give a brief explanation. You've probably already figured out the answer by now, but this might help someone else searching in future.
The key concept here is "asynchronous execution".
When you subscribe to a channel using the basic_consume method, you are not asking for the callback to be executed once, immediately, but for it to be executed once a message becomes available, and then every time another message is available.
In the case of AMQPLib, you wait for new messages by repeatedly calling the wait() method; i.e. here:
while(count($this->channel->callbacks)) {
$this->channel->wait();
}
Thinking about this carefully, there are two mistakes in your code:
The line return $msg->body has nowhere to return to. The call will happen somewhere deep in the implementation of the wait() method, and you get no output from $this->channel->wait(), so have no way of doing anything with that returned value.
On the other side, when you call $objRMQ->subscribe("someQueue") from your other class, you are expecting it to return something, but that function has no return statement. The only return statement is inside the anonymous function you passed to basic_consume.
The solution is basically to do all your processing of the message - echo $msg->body, or whatever real processing you want to do - inside the callback. If you really want to gather data as messages come in, you could save it to some variable accessible outside the callback, but remember that you will at some point need to break out of the wait() loop in order to do anything with that data.

API response - gathering errors from included classes

I'm working on a RESTful and am stuck on message gathering for returning to the user. Basically, depending on the options selected, a few classes will be included dynamically. I'll try to provide a real-world break down. We have a HTML-email-tempalte maker - depending on the template chosen a php script will be included. This script may have warnings and I need to pass them "upstream" so that the API can report them. So we have something like this ( -> = includes )
API -> HTMLGenerator -> (dynamically) template-script.php
I need the template-script to be able to report errors to the API controller so the API can report them to the API user. Not sure the best way/practice to accomplish this.
So far , my thoughts are maybe a singleton or session variable that the template-script can add messages to, then the API Controller can report them. Any thoughts?
Main API
REST create by POST to /v1/html basically just:
class API {
require($dynamic_script);
$errors = array('warnings'=>array('warning1',waring2'));
//set http header and return JSON
}
HTMLGenerator
class HTMLGenerator {
//basically some wrappers for junior / non-programmers
function addHeading($text) {
//Add a header and do some checks.
if(strlen($text) > $warnTooLong )
HTMLErrors::addWarning("Message");
}
}
Dynamic Script
$h = new HTMLGenerator();
$h->addHeader($text);
$h->addImage($imageUrl);
You need to use a custom error handler.
See this link - http://php.net/manual/en/function.set-error-handler.php
It allows us to handle a error that might be thrown to capture it and process it. So, when you capture it, you can pass this to the parent class and furthur upstream for further processing.
Global object would work, set_error_handler too, but these are just hacks. The cleanest option is to modify your app elements to do what they are suppose to do - return those messages.
These shouldn't be too hard to do:
function myOldFunction($param1, $param2)
{
// do something
}
modify this way:
function myOldFunction($param1, $param2, array &$messages = array())
{
// do something
$messages[] = 'hey mama, i\'m on stack overflow!';
}
usage:
$messages = array();
myOldFunction(1, 2, $messages);
print_r($messages);

Categories