I'm beginner to symfony.
I have a twig template with 2 buttons that calls an external .js that executes an ajax call.
Button 1 calls function 'delete', and this is the js code:
var path = $("#abc").attr("data-path");
/*grabs it from some div in the twig template.. <div id="abc" data-path="{{path('delete')}}"></div>*/
function delete(n){
$.ajax({
type: "POST",
url: path,
data: {id : n},
"success":function(data){
alert('ok');
}
});
}
Button 2 calls function 'edit' which is the same code except that the 'url' goes to another 'action', and the 'data' is not a json, (it is data: formData)
Routing.yml for function delete is:
delete:
pattern: /delete
defaults: {_controller: TPMainBundle:Default:delete }
And this is the controller action:
public function deleteAction()
{
$id = $_POST['id'];
/*other code to work with doctrine making queries to delete from database*/
}
(The js code is from a webpage done without symfony and it works fine)
I was told the right way to retrieve the POST in the action, reglardless it was whether a json or formData, was using the same that I used in PHP:
$id = $_POST['id'];
Here, I have 2 problems.
First, I don't know if this is correct because it doesn't work.
Second, I don't know how can I know if i'm retrieving the POST OK !!
When I did this without symfony, I checked if I was getting the POST with the command 'fwrite', because the ajax went to a PHP file instead of an Action, and then with the command fwrite I created a .txt file with the output of an echo to see if the $_POST was recovered or not.
But here in symfony I don't know how to check it, so I'm driving myself crazy.. trying to implement the solutions I read without being sure if they work..
and with the extra problem that since I'm newbie for me it's a bit confusing trying to install some external bundles for debug. Please help
The correct approach for acessing post or get params is using Symfony's Request object. You can pass it as an argument of a controller action, or retrieve it from the controller directly. Here's two examples:
public function deleteAction(Request $request)
{
if ($request->isMethod('POST')) {
$id = $request->get('id');
}
}
Without passing the Request as a parameter:
public function deleteAction()
{
if ($this->getRequest()->isMethod('POST')) {
$id = $this->getRequest()->get('id');
}
}
Extra tip for people who comes from PHP and doesn't know how to check if they are retrieving the POST or not: - send it to a .php
public function deleteAction($request)
{
$id = SOME RETRIEVED CODE YOU AREN'T SURE YOU ARE RETRIEVING THE RIGHT WAY;
/*you can send this variable to a view, symfony allows you to use .php files but you have to name their extension as html.php not just .php*/
return $this->render('TPMainBundle:Default:test.html.php', array('id' => $id));
}
And then, in that view:
<?php
echo $id;
$myfile = fopen("somename.txt", "w") or die("Unable to open file!");
$txt = 'Id is: '.$id;
fwrite($myfile, $txt);
fclose($myfile);
This will generate a .txt
So, you can open the .txt and check if you have recovered the DATA or not!
The file will be located inside the 'web' folder..
The other tips is to check the 'app/log/dev.log' thanks #Zain Saqer
In Symfony you get your POST data from the current Request object (That's how we do it in Symfony), one way to get the current Request object is by adding $request variable as first parameter in your action function.
Your action function could be like this:
public function deleteAction(Request $request)
{
//check if our POST var is there
if($request->request->has('id')){
//it's there
$id = $request->request->get('id');
/*other code to work with doctrine making queries to delete from database*/
}else{
//it's not there!
}
}
Regarding installing third party bundle, use Composer to do this task for you, and don't forget to add the class path of the installed bundle to $bundles array in AppKernal class. Follow this link to know how to do this.
Related
So I have three different separate files:
functions.php (all functions for the database)
main.html (my main program)
main.js (all javascript functions)
Now, I want to call a function in PHP through AJAX. To do that, I need to pass $conn.
$conn = sqlsrv_connect($serverName, $connectionInfo);
It's a resource, so I can't use json_encode.
The way I set the everything up now is that the php-file is required in the html so I can use the functions and when I change the
value of a dropdown, the js is called.
How can I pass the $conn variable to Javascript?
Regards
It doesn't work like that.
You should never be directly making calls to the database from the front-end.
Think of it as three separate levels. Your HTML/JS is the front-end, your PHP is your server, and your Database is on its own level.
So when the user does something on the front-end, say changes the value of a field and you want to update that in the database the following actions should happen:
Event triggers on JS
AJAX is called as a result of the event being triggered
PHP server receives the AJAX request and executes code to modify database
(optional) PHP server sends something back to the front-end to tell it that the request was successful
Read up on the concept of MVC: https://developer.mozilla.org/en-US/docs/Web/Apps/Fundamentals/Modern_web_app_architecture/MVC_architecture
Try this in php code as I assume functions.php
$conn = sqlsrv_connect($serverName, $connectionInfo);
echo $conn;//Don't try echo anything other
In Javascript
$.ajax({
type: "POST",
url: "functions.php",
success: function(data)
{
var conn = data; // here is your conn which comes from php file
}
});
First of all include jquery latest version from cdn
Create an API Url, and use POST method
site.com/api/insert.php // to insert into table
Use $.post() api of jquery to send data
var url = ""; // enter your URL HERE
var postData = {}; // object of post data with table name, cols and values
$.post(url, postData, function(data, status) {
// do what ever you want with data
})
ps: you can also create diff insertion / selection / update / delete api for different table. (recommended)
Read more about $.post() here
I'm using Slim for development. All my GET routes are working just fine, but whenever I use POST, I get "unexpected result". Please have a look at how I've implemented slim and that "unexpected error".
index-routes.php (index root file)
<?php
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim(array(
'debug' => true
));
require_once 'site-index.php';
require_once 'routes/default-routes.php';
$app->contentType('application/json');
$app->run();
?>
routes/default-routes.php
<?php
$app->post('/login',function(){
echo 'AllHailSuccess!';
})
?>
origin of POST request called via AJAX
function try1()
{
var value1 = "afsfesa";
API.call('/login','text','POST',function(data){console.log(data)},{var1:value1});
}
AJAX Call API
var API = {
call:function(url,returnType,reqType,callback,data){
var data = (!!data) ? data : {};
var callback = (!!callback) ? callback : function(){};
$.ajax({
dataType: returnType,
type:reqType,
crossDomain: true,
xhrFields: { withCredentials: true },
url: url,
data:data,
success:callback,
error:function(data){
console.log("Error!");
console.log(data);
}
});
}
}
"Unexpected error": When I execute try1(), THE POST ROUTE DOES GETS EXECUTED SUCCESSFULLY but the contents (The entire code in plain-text) of site-index.php (Which I called in root index-routes.php file) also gets logged along with it. The reason why I imported site-index.php in the first place, is because it acts like a "main stage" for my site. It's the only page I want to load and user navigates within it.
I want to know:
Why I'm getting this type of output?
Is my approach alright? I think importing my main-stage file from index- routes is causing this. Is there any other way of doing this?
Any help is appreciated. Thank you.
Your Slim calls are going to return anything that is displayed on the page.
There are a few ways to work around this:
Nest all of your page renders inside the route and don't render full pages for AJAX routes.
Modify your AJAX calls to search the returned DOM to find the relevant information.
In your example shown, AllHailSuccess! will be displayed after all of the content in site-index.php
Many people use templating software to render their pages and then use a service to render their page via the template. For more basic sites, I would recommend you create a simple service to display content.
Here's a simple example of a Viewer class I use in my project(s)
class Viewer {
/**
* Display the specified filename using the main template
* #param string $filepath The full path of the file to display
*/
public function display($filepath) {
//set a default value for $body so the template doesn't get angry when $body is not assigned.
$body = "";
if (file_exists($filepath)) {
$body = get_include_contents($filepath);
} else {
//You want to also return a HTTP Status Code 404 here.
$body = get_include_contents('404.html');
}
//render the page in the layout
include('layout.php');
}
}
/**
* Gets the contents of a file and 'pre-renders' it.
* Basically, this is an include() that saves the output to variable instead of displaying it.
*/
function get_include_contents($filepath, $params = array()) {
if (is_file($filepath)) {
ob_start();
include $filepath;
$ret = ob_get_contents();
ob_end_clean();
return $ret;
}
return false;
}
Your routes that you want to display the page layout to the user should look something like this now:
$app->get('/', function() {
(new Viewer())->display('home.html');
});
This is by no means a comprehensive solution because it does not address proper HTTP status codes and files are referenced directly in your code which can get messy, but it's a good starting point and its quick to mock something like this up.
If you want to continue in this direction, I would recommend you take a look at the Slim v2 Response Documentation and create a class that constructs and returns Response objects. This would give you much more flexibility and power to set HTTP status codes and HTTP Return headers.
I highly recommend checking out Slim v3 Responses as well because Slim 3 uses PSR-7 Response objects which are standard across multiple frameworks.
Translate translator from Google. So that did not swear if something is not clear. Itself from Russia.
The question arose. How to pass the value of the alert in the javascript in the variable $ value in php, and write it in the case file. And another question: how to hide the alert? or use instead to visually it was not visible, but the value was passed?
//a lot of code
{
console.log(data);
alert(data['value']);
}
});
So. Also there is a PHP script that writes logs (current page and the previous one) to a file. According to this principle here:
//a lot of code
$home = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$referer = $_SERVER['HTTP_REFERER'];
$value = how the value of the java script to convey here?;
$lines = file($file);
while(count($lines) > $sum) array_shift($lines);
$lines[] = $home."|".$referer."|".$value."|\r\n";
file_put_contents($file, $lines);
It is necessary that the value of js is transferred to the php-script and write to the file. How to do it? Prompt please. I am a novice in all of this.
PHP scripts run before your javascript, which means that you can pass your php variables into javascript, but not the other way around. However, you can make an AJAX POST request from JavaScript to your PHP script, and grab the POST data in PHP through the global $_POST variable.
Assuming you use jQuery, your JavaScript would look something like:
// assign data object:
var data = { value: "test" };
// send it to your PHP script via AJAX POST request:
$.ajax({
type: "POST",
url: "http://your-site-url/script.php",
data: data
});
and your PHP script would look like:
// if the value was received, assign it:
if(isset($_POST['value']))
$value = $_POST['value'];
else
// do something else;
I want to use jquery ajax to change the content of my div elemnt by requiring different php files.
here is the ajax code :
$.ajax({
url:"/project/Functions/project_functions.php",
type:"POST",
data:{
functions:num
},
success:function(result){
$("#right_bot").html(result);
}
});
the project_functions.php would be something like :
$result = '<?php require "Panels/Project/Main/main.php" ?>';
echo $result;
I can see the value being outputted , but the html comment out the php part
<!--?php require "Panels/Project/Main/main.php" ?-->
It just comments out the php. Is there a way i load different php files into my div ?
In the main.php file , It has php code , html code , and some style tags. Can I use ajax to load all this into the div element ? or I have to echo all my html code ?
You can't do this like that. What you want is that all PHP is excecuted on the server and only the result has to be returned.
You can't send php-code back to javascript and try to run it there, PHP is a serverside language, it will only work on the server. Javascript is clientside, it will only run in the browser.
If you where to send <?php echo 123; ?> back to Javascript, you'll get exactly that as result, not 123.
The solution in your case is to make project_functions.php really require it. This will include the main.php, all it's functions and output.
require "Panels/Project/Main/main.php";
Some suggested reading:
http://www.codeconquest.com/website/client-side-vs-server-side/
A trick which might help you: Paste the link to your urlbar, and add the variables to it. The result you get in your screen is what Javascript will output. Note: This only works for method=get, not post.
In this case browse to /project/Functions/project_functions.php and do the simple require per my code above. That output will be send to Javascript.
Send a parameter in the ajax request 8for example type):
$.ajax({
url:"/project/Functions/project_functions.php",
type:"POST",
data:{
functions:num, type: "main"
},
success:function(result){
$("#right_bot").html(result);
}
});
And then in php-file get the type variable:
if($type == "main") {
require "Panels/Project/Main/main.php"
}
else {
require "Panels/Project/Main/sthelse.php"
}
You should also have some sort of same function name or something to output the results of the file;
<?php
function printResult() { }
echo printResult();
Try:
$result = file_get_contents('Panels/Project/Main/main.php');
I'm using phonegap and I'm trying to send an array encoded as json from a controller to view.
In my controller (server side):
$users = Model_Users::find(1);
$a=$users->to_array();
return json_encode($a);
In my view (into smartphone application using phonegap):
$(document).ready(function() {
$.ajax({
url: 'my/url...',
method: 'POST',
data: {
},
success: function(data) {
alert(data);
}
});
});
This working fine, infact in the view I get this alert:
data = {"name":"Jhon","surname":"Larry","age":"25"}
This work because the result of the query is only one row.
Instead when I try to get more than one query result, example:
$users = Model_Users::find('all');
$a=array();
foreach ($users as $user){
array_push($a,$user->to_array());
}
return json_encode($a);
In this case an empty response comes up, in fact I get this alert:
data = []
What is the problem?
Thanks in advance
I will try to build an answer with some tips based on what we already know thanks to the comments.
First of all now we are sure that the JSON is valid (jsonlint.com for example).
So,now, we are completely sure that the problem resides on the PHP / server-side.
My solutions:
Pay attention to not echo/return something before the value you need;
Change return with echo;
Add an exit; statement after the echoed value to be sure that no other characters will be included in the server answer;
Not exactly needed, but you can even think to set the header('Content-Type: application/json');
Debug looking at the console and using console.log instead of alert() (there are a lot of threads explaining the difference
Hope this will help!