I'm working with CodeIgniter 3 and I would have some advices about where storing scripts. I want to call with jQuery a php script that will send JSON datas to my Javascript function.
How to do a connection with my database inside this script using CodeIgniter database config file?
Here is my jQuery callback structure :
<?php
session_start();
header('Content-Type: text/json');
error_reporting(E_ALL);
ini_set("display_errors", 1);
$callback = array();
echo json_encode($callback);
I've stored this script in app/callback folder that I have made, but I don't know if I should store it outside app folder or not... How do you structure your CodeIgniter's projects?
Thanks for your advices :)
setup;
in your application/config/database.php configure your database connection
in your application/config/autoload.php ensure that the database library is enabled
here for more info for database setup
model;
in application/models/ create your thing_model.php which functions for accessing your database. for this example public function get_data() this function would produce your database JSON data output when called
here for more info to query your database
controller;
in your application/controllers/thing.php create an ajax function;
public function ajax()
{
if ($this->session->loggedin && $this->input->is_ajax_request()){
$action = $this->uri->segment(3);
if ($action === "pull"){
$forms = $this->thing_model->get_data();
//actions here
}
if ($action === "test"){
//actions here
echo "hello world!";
}
} else {
redirect('/homepage');
}
}
whats happening;
if ($this->session->loggedin && $this->input->is_ajax_request()){
here you are checking for security and that the request is ajax in nature
$action = $this->uri->segment(3); is grabbing a segment from the URI for actioning. eg. http://example.org/controller/ajaxmethod/this_action
if ($action === "pull"){ is returning data if your ajax was invoked to http://example.org/thing/ajax/pull
ajax;
in the jquery JSON ajax in your .js file (load the .js file in the footer of your view)
$('#buttonAction').click(function() {
//Jquery Ajax code here
$.ajax({
method: "POST",
dataType: "json",
url: global_path + "thing/ajax/pull",
data: { user_id: "1", data: "ABC" }
})
.done(function( data ) {
//process your JSON data here
});
});
whats happening;
jquery ajax datatype see here
url: global_path + "thing/ajax/pull", calls your controller ajax() method with the pull action.
notes;
in your __construct for the controller i would recommend putting in some testing here to secure only ajax requests to your function, and not the others for strict operations and unwanted unknowns.
you could put ajax to another controller if it suits your application. but this can create security headaches with duplicating checks etc.
If you want to call backend functions from jQuery you have to go with AJAX. Check docs here. See a simple example below.
$.ajax({
method: "POST",
url: "PATH_TO_YOUR_CONTROLLER_FUNCTION",
data: { field_name1: "Field value 1", field_name2: "Field value 2" }
}).done(function( msg ) {
console.log(msg);
});
If you have this script in your view (which is a php file), you'll be able to use php functions to set the path. For example:
url: "<?php echo base_url('your_controller/your_function')?>"
The db connection and all logic stays in the controller and is implemented as usual.
Related
I am new to php and am trying to update a hidden field value inside a php function and can't see to find a solution that works.
In template.php I have:
<input type="hidden" id="variable_ID" name="variable_name" value="variable_value">
This works fine.
However I need to update the value of the variable to the record ID of inserted record in a function in functions.php eg
function myFunction() {
$insert_record = $mydb->query("INSERT INTO `Table`(`Name`) VALUES ('John')");
$get_record_id = $mydb->insert_id;
// *** Set Hidden field value to $get_record_id here ***
}
I have tried a myriad of things but can't seem to find a solution.
Any pointers on how to solve this problem?
Here is the solution I used - thanks to #Steven and #El_Vanja for direction.
(I may need to change the question title now though because what I actually needed to do was return a variable to javascript from PHP using Ajax. I didn't need to use hidden fields).
PHP
function myFunction() {
$insert_record = $mydb->query("INSERT INTO `Table`(`Name`) VALUES ('John')");
$get_record_id = $mydb->insert_id;
echo json_encode($get_record_id);
exit;
}
JS
jQuery.ajax({
url: ajax_url,
type:'POST',
data: {
action: "myFunction",
anydata:"to be posted"},
success: process_record_ID
});
function process_record_ID(data_returned_from_myFunction){
recordID = data_returned_from_myFunction;
}
Hope this helps others!
Notes
I believe that we have to declare 'process_record_ID' as a separate function outside of AJAX because AJAX is asynchronous. If we define the function in the success handler, the function runs in AJAX before the value is actually returned from PHP.
In the AJAX success handler, we don't need to explicitly list the 'data_returned_from_myFunction' variable in the call to process_record_ID function. When the data is returned to the AJAX success handler from PHP, it still gets sent to the function.
Additional answer
You're correct AJAX is an asynchronous construct which means that certain tasks can be carried out before you might expect them to (from a synchronous perspective).
For example we can (as per the code in the original answer) use jQuery to update the value of a field directly in the success handler.
We can't update a JS variable directly, i.e:
some_variable = response.value;
If you attempt it the variable some_variable will likely be undefined.
The difference comes down to callbacks:
Callbacks allow the asynchronous function to call a function after it completes. Where as setting a variable happens on the spot.
There are two easy ways to solve this issue then:
Create a function outside of the AJAX request and allow it to callback that function once the AJAX request has completed -- as you've already discovered.
Use the complete option inside of your AJAX request.
Using a call back
Firstly we need to define out variable to be updated and the function which we will use to update it:
var inserted_id = "";
function update_id(data){
inserted_id = data.record_id;
}
Then we can make out AJAX call:
$.ajax({
type : "POST",
url : "/url/to/functions.php",
data : {data:"to be posted"},
dataType: 'json',
success : update_id
});
N.B.
Calling update_id in this fashion means we pass the entirety of the returned JSON object; not just the returned number.
Alternatively...
var inserted_id = "";
function update_id(data){
inserted_id = data;
}
$.ajax({
type : "POST",
url : "/url/to/functions.php",
data : {data:"to be posted"},
dataType: 'json',
success : function(response){
update_id(response.record_id);
}
});
This method is effectively the same but we only pass the returned number to the update_id function.
Using complete
complete works the same way as success however activates once the AJAX request is... complete...
var inserted_id = "";
$.ajax({
type : "POST",
url : "/url/to/functions.php",
data : {data:"to be posted"},
dataType: 'json',
complete: function(data) {
inserted_id = data.responseJSON.record_id;
}
});
Original answer
Having not seen the rest of your code giving a complete answer is tricky. However, this should set you on the right track:
PHP
Firstly, in your PHP you need to make sure and output the data that you want returned to the webpage. In this case we want to return the insert id of the newly created record; to do this we're going to output a JSON object so that the AJAX call can interpret the value and update the page:
function myFunction() {
$mydb->query("INSERT INTO `Table`(`Name`) VALUES ('John')");
echo json_encode(["record_id" => $mydb->insert_id]);
exit;
}
N.B.
We don't want any output other than the JSON string. Hence exit has been used after the echo. You may want/need to adjust the echo and exit to fit with the rest of your code etc.
JS
Now that we have our PHP returning usable data to our ajax call (which should look something like the below) we can take the returned data aka response and update the value of the hidden field accordingly.
$.ajax({
type : "POST",
url : "/url/to/functions.php",
data : {data:"to be posted"},
dataType: 'json',
success : function(response) {
$("#id_of_hidden_field").val(response.record_id);
}
});
I am having some issues running an AJAX request to the php class that contains the AJAX request. The AJAX request is called used a button, and works partially.
My AJAX request is held in a header.php file, which is included in my kpi2.php. If I specify the "url" for the AJAX call to a test file (in the same directory) the POST is successful and I can see the output. I was under the impression if I removed the "url" option it would indeed post to the same page, what am I doing wrong here?
function executeRefresh(){
if (control){
$(".loader").show();
$.ajax({
type: "POST",
data: { refresh: '1' },
success: function(json) {
if(!json.error) location.reload(true);
$(".loader").hide();
}
});
}
}
Output when no url is specified (meaning it should be posted to the same file that is calling the AJAX)
Written from /home/kpi/pages/kpi2.phpArray
(
)
This is the output when I have the option url: "test.php" (which has the exact same output but just in a different file.
Written from /home/kpi/pages/test.phpArray
(
[0] => refresh
)
EDIT:
To obtain the output generated from above, a simple export.
$v1 = print_r(array_keys($_POST),true);
$fp = fopen('../data/output.json', 'w');
fwrite($fp, 'Written from /home/kpi/pages/test.php'.$v1);
fclose($fp);
As for the control variable, it is just a simple listener that is true/false depending if the control key is clicked. It does indeed work and I've never had issues with it before.
As for the location.reload() I tried removing it and now it seems that it isn't even writing the php code now.
Originally in the header.php I had a button on the navbar that would call the AJAX function thus having the kpi2.php (which included the header.php) to have something posted to it. Once it was posted it would then call another php class.
Instead what I did was get rid of the onclick=executeRefresh() and then just listened to the button press specifically in the kpi2.php class. This way I could instantly execute the AJAX request to the other class without the un-needed post request to the class.
$(function() {
$(".btnRefresh").click( function()
{
if (control){
$(".loader").show();
$.ajax({
url:"../setup/kpi_quality.php",
type: "GET",
data: { casp: 'AVANT-CAP-321' }, // name of the post variable ($_POST['id'])
success: function(json) {
//if(!json.error) location.reload(true);
$(".loader").hide();
}
});
}
}
);
});
I have been researching and trying to learn the proper method to accomplish this. I have done the following but, I still have no change on my form. Is there anyway to see if the ajax call is even being made? Could anyone correct this code to figure out why I am not getting any change on the field in my form.
In my model I have the following function
public function standardRate($country)
{
$country_std_rate = Yii::app()->db->createCommand()
->select('AVG(rate_syr_mh)')
->from('packaging_metrics')
->where(array('like', 'country', '%'.$country.'%'))
->queryRow();
echo CJSON::encode($country_std_rate);
}
In my controller I have added this function as well as added 'countryRate' to my access control for all
public function countryRate()
{
$input_country = $_POST['country'];
$model = PackagingMetric::model()->standardRate($input_country);
echo CJSON::encode($model);
Yii::app()->end();
$this->render('countryRate',array(
'model'=>$model,
));
}
This is my Jquery call in my form
$('#PackagingMetric_std_rate').live('click',function()
{
var country = $('#country').val();
$.ajax({
type: 'POST',
url: 'PackagingMetric/countryRate',
data: {country:country},
success: function(data)
{
$('#PackagingMetric_std_rate').html(data);
}
});
});
However, nothing on my form changes with a value, I am using Yii-Debug-toolbar and not seeing any POST calls or any sql queries upon clicking the appropriate field on my form.
Rename the function in the controller to actionCountryRate()
When a post request is made to a controller, it looks for an action using the action prefix.
Your url parameter for the $.ajax(); is wrong could be wrong.
That is if you are not hiding the entry script (index.php), you will have to write:
url: 'index.php/controllername/actionname'
instead of:
url: 'controllername/actionname'
It would be better to use createUrl():
url: '<?php echo $this->createUrl('PackagingMetric/countryRate'); ?>'
(Ofcourse the echo above and how you include php code in js will depend on how you are including the js in the first place)
And name your countryRate as actionCountryRate().
I consider to use absolute url while firing an ajax call.
Try to make your url in this way, it will solve your problem.
url: '<?php echo Yii::app()->createAbsoluteUrl('PackagingMetric/countryRate'); ?>',
and your controller action name should be "actionCountryRate" because this function is hit from url, not internally called from controller, also set its accessRule if you are using access control otherwise the function will not execution.
I am developing a web app and as usual I write lots of php file in order to support my ajax call.
I was wondering if there is any way to write a unique php file and get data from this unique file.
For example if I write lot of functions into my php file I cant get data from a specific function I wondering.
Yes, you can. It 's a matter of designing your file to work with parameters for different calls. A very simple example:
<?php
function action1() {}
function default_action() {}
var action = isset($_POST['action']) && (strlen($_POST['action']) > 0)
? $_POST['action']
: '';
switch(action) {
case "action1":
action1();
break;
default:
default_action();
break;
}
?>
Having a similar file, you can then call methods in it using a hidden action field. To call action1, you would use something like this in your ajax call:
$.ajax({
url: "thephpfile.php",
type: "POST",
data: { action: "action1" }
...
});
I am building an application with codeigniter and I want to post some data using jQuery but for some reason it doesn't work. Here is the code what am I doing wrong ?
$.ajax({
url: "<?=site_url('requests/save')?>",
type: "POST",
data: data,
success:function(msg){
alert(msg)
}
});
I haven't written any code in the controller yet, just something simple to test it. Also as long as javascript is concerned that's about it. The ajax is trigered when the user clicks a button.
function save()
{
if($this->input->is_ajax_request()) {
echo 'ajax';
}
else
{
echo'sdfs';
}
}
Dante,
First make sure you load your helper:
$this->load->helper('url');
Also post the JAVASCRIPT for us, not the PHP. The Javascript is what is failing, not the CI PHP. You might have a PHP issue also on your controller for 'requests/save', have you checked that?
I believe you need to pass a cross site request forgery token.
If you set XSS to true in your config, then your form helper creates a hidden field that is required to be passed to your server.
Make sure you are properly collecting your form data. Easiest to use jquery the .serialize() function.
Load the url helper in the autoload.php. Your url in the ajax call should just be 'requests/save'.
Also php shorthand echo tags are a bad practice stick to
<?php echo ?>
for better code portability
Moved my comment to an answer
EDIT : to test the ajax, use the relative url instead use a php tag inline in your js, to your controller, which will work in any condition (in CI) whether you already removed the index.php from your url (using htaccess) or not by include the index.php in your url.
$.post('/index.php/request/save', { foo: 'bar' }, function (html) {
alert(html);
});
At targeted controller
function save()
{
if($this->input->is_ajax_request())
{
echo $this->input->post('foo') ? $this->input->post('foo') : 'Not Bar';
}
else
{
echo'Not from AJAX';
}
}
EDIT :
also make sure you have already load the url helper before using its function
$this->load->helper('url');