Implementing rjs in php - javascript

I want to implement a pretty basic rjs kind utility in php. For those who have no prior knowledge of it, the rjs utility in Ruby on Rails returns application\javascript content-type for ajax requests. This is pretty handy when we want to change the inner html of two different divs through ajax in one request.
So what I need is to read html stream of some *.tpl.php file so that from the server side code, I can return javascript strings as:
$rjsStr = "$('#div1').html(".Util::getHtmlFromTpl($outputParams1, 'tplfile1.tpl.php').");";
$rjsStr .= "$('#div2').html(".Util::getHtmlFromTpl($outputParams2, 'tplfile2.tpl.php').");";
return $rjsStr;
Now my ajax request would look like $.ajax({url:'/controller/action.php?param1=1&param2=2',success:function(result){eval(result);}})
Edit The problem is that I don't know how to get the html stream of php file. I simply tried include('path_to_file/tplfile1.tpl.php'); but that doesn't return the html stream as a variable.
PS: I don't want to use file_get_contents for the security reasons.

include('path_to_file/tplfile1.tpl.php'); includes code and executes it. If you need to just read the file, then you may use file_get_contents, but I suppose, you need rendered template as input.
Then you need to use output buffering.
ob_start();
include('path_to_file/tplfile1.tpl.php');
$rendered_tpl = ob_get_clean();
// now you may strip excessive part, escape html and do with it whatever you want

Related

How to pass a string with special characters in php so I can display it on page

I have an index (fscrawler) of pdfs, docs and spreadsheets. I wrote a php script to search the index and display the contents of the documents (opens up in a modal). Below is the code to open the modal with the documents details. However I am unable to view the documents,
I would like to preserver the documents original format(indentations and bolds). kindly advice.
<button type="button" onclick="searchDetails('<?php echo $r['_source']['file']['filename']; ?>',
'<?php header('Content-Type: text/html; charset=UTF-8');
echo htmlentities( $r['_source']['content']); ?>',
'<?php echo addslashes($r['_source']['path']['real']); ?>',
'<?php echo $q ?>')"
class="btn btn-info btn-sm openBtn" data-toggle="modal" > Details </button>
Catching the syntax errors in the browser console is a good first step. Next, look at the source of the rendered page. As a PHP developer, your job is to output valid html, css, and in your case JavaScript to get your page to render. When you get a Syntax Error in the console, that means JavaScript. It runs browser side so it has to be debugged in the browser.
What you're trying to do here is write out a JavaScript invocation of the JavaScript searchDetails() function. But what are you hoping to accomplish with the php header call? I dont know what searchDetails does, but header applies to the page php is rendering. It wouldn't apply to the file content. You can have a Content-Type header for the webpage, but you can't put a header in a JavaScript string. You can put the string value of a header in JavaScript but that won't actually describe the content-type of anything to the browser.
I suppose htmlentities might be sufficient to expose the content of your files, but pdfs, docs, and spreadsheets are going to look very funky that way. not sure exactly what you want it to look like, but you're probably going to want to serve the content of these files with distinct http requests so they can have distinct headers (esp Content-Type). I can't make sense of how htmlentities(spreadsheet_content) would be a valuable string to display.
Generally speaking, rendering JavaScript from php (or any templating thing) is a pattern I suggest you avoid. Write static JavaScript and have a clear mechanism to expose data to JavaScript. It's fraught with difficulties, including being very difficult to write (quoting and escaping for js, php, html all in the same code ) and debug (eg your syntax error), and often fails to be robust in the face of further development.
I would probably generate a json file that described the file data and then would read that through JavaScript and render the page from it with a js library, probably Vue.js. As I mentioned I would build a separate php resource for serving the file content so I could add a ContentType header on that. If you do this, make absolutely sure you're not serving files outside of your index. It might be wise to request files from their position in the index if possible rather than by path to avoid requests exposing eg /etc/shadow.
If you want to make webpages think of that as primarily JavaScript centered development. Use PHP to generate data but try to keep your HTML and JS as static as possible. Choose a JavaScript library - do not fall into the trap of thinking raw js is "simpler" or "more straightforward"; it's not. If you don't have a preference I recommend Vue but Angular, React, even d3.js would all work here. Your data contracts will be more explicit and you'll be able to develop the backend and the frontend in isolation, providing some confidence that the backend works as you hack out JavaScript end. This might seem like a big complication to break things out this way, but if you give it a try, I think you'll experience pretty quickly how much easier it is.

How to prevent XSS in a JavaScript platform using a PHP JSON API?

I'm looking for a way to prevent XSS in my pure javascript platform which calls a PHP API that returns JSON data using json_encode().
Take this basic example:
<script>alert('hello world');</script>
Let's say the above is stored in a database field which is grabbed by PHP and returned to the browser using json_encode():
<?php
echo json_encode(array('name'=>"<script>alert('hello world');</script>"), JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS);
?>
As you can see, i've used a few json options in hopes this would sanitize the data for javascript usage. However, when I do the following in JavaScript, the alert still executes:
<script>
$('.nameField').html(jsonData.name);
</script>
From what i've read, the json options are the best practice for json_encoded data, but yet it still executes.
Where am I going wrong?
You're looking at the wrong layer. The threat here is not the JSON, it is the HTML inside the JSON. (There might be a threat in the JSON layer too, there isn't enough information in your question to tell.)
The options you've provided look like they should successfully prevent an XSS attack if you were to echo the JSON into a <script> element in order to cause it to be parsed as an array literal.
… but that isn't what you are doing.
You have done something unspecified to put the parsed JSON into a variable called jsonData.
At this point, any JSON-specific XSS protection is irrelevant. It is past the point where it matters.
You are taking the HTML out of the JSON and processing it with jQuery and injecting it into the DOM.
The way to defend against that is to not tell jQuery that it should treat it as HTML.
Use the .text() method instead of the .html() method.
Cover it with htmlentities($javascript, ENT_QUOTES | ENT_HTML5, 'UTF-8');.
If you need to show exact HTML on the page use one of PHP libs like htmlpurifier.
However, you can still insert it with JQuery .text() instead of .html() as mentioned below, but it's better to escape it if possible.

Pre-compiling PHP functions with Ajax

I have a question about compiling server side functions in PHP with Ajax. I am trying to understand what happens when multiple asynchronous calls are made to the same server side script.
Lets say that I have the following php script - "msg.php":
<?php
function msg(){
$list1 = "hello world";
return $list1;
}
echo json_encode(msg());
?>
and call Ajax JQuery like this:
function get_msg() {
$.get("msg.php", function(data){console.log(JSON.parse(data));}) }
with a button in html:
input type="button" onclick="console.log(get_msg());" value="Submit" class="btn btn-info"
Assuming that everything works I am trying to understand the following:
Does the server recompile the "msg" php function each time a user clicks the button? Does it (or can it?) manage this by user? How about by session?
After multiple clicks by different users does the server destroy the "msg" function after each request? Can I save multiple versions of the same function in memory for later use? If so is it possible to reconcile the different versions?
Is there a way to pre-compile a single php function for all Ajax requests?
Is there a "proper" way to handle dynamic function calls on the server side?
I feel like recompiling it on the server side is wasteful but perhaps this is how things are supposed to work.
PHP interprets code on each request. But there is OPcache:
OPcache improves PHP performance by storing precompiled script bytecode in shared memory, thereby removing the need for PHP to load and parse scripts on each request.
This extension is bundled with PHP 5.5.0 and later, and is available in PECL for PHP versions 5.2, 5.3 and 5.4.
You can find here on SO how to enable OPcache:
Add the following line to your php.ini:
zend_extension=/full/path/to/opcache.so (nix)
zend_extension=C:\path\to\php_opcache.dll (win)
... and much, much more!
I think what you're looking for is caching. PHP by default is a scripted language so if you need to reference something repeatedly it will be executed each time since its interpreted not compiled. Caching is a way around that.
There are a few ways I can think of to store this data for later use. One is cacheing in plain text. Write out your result to a text file and then reference that for later use, using the last modified date as a way to check for freshness. I'm not a big fan of this method because I think having extraneous files written to the server is messy. (just my opinion)
http://php.net/manual/en/function.file-put-contents.php
Thats the function you would use to store your result.
Another option is writing to a database for the results and then time stamping it so you can reference that for freshness. From there you could just use PDO or mysqli to retrieve the data. Then you could use a database cache to make the response time more performant.
Another option is just using something like OPCache to store the results of the function in memory on repeated calls. ( I don't have much experience in this though )
Hopefully that puts you in the right direction.

I would like to read $_FILES with a Javascript loop [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Here is part of my Javascript function:
var x=document.getElementById('DigitalFiles').rows[R].cells;
x[0].innerHTML= $_FILES['files']['name'][1] <<<< this $_FILES is not working !
What syntax will work, please.
It seems you are confusing javascript with PHP or vice versa.
To set x[0].innerHTML to the desired value, you could use this:
x[0].innerHTML=<?php echo $_FILES['files']['name'][1]; ?>;
Or, if you are already generating the javascript code directly in PHP:
<?php
echo 'x[0].innerHTML="'.addslashes($_FILES['files']['name'][1]).'"';
?>
Generally
You cannot loop through a PHP array in javascript - unless you first make it's contents available to javascript:
<script type="text/javascript">
var _arrayFromPhp=[<?php
implode(',', $_arrayInPhp);
?>];
</script>
This would work, generally, so that you can then use _arrayFromPhp in your javascript environment. This rather abstract example also assumes that $_arrayInPhp is an array with only one level.
However, in the particular case of $_FILES this doesn't make much sense because PHP fills the $_FILES array with files that are being uploaded by the client. I cannot think of any purposeful way to process the contents of $_FILES in javascript.
If you want to use it anyway, you could go about it like this:
<script type="text/javascript">
var _arrayFromPhp=<?php
json_encode($_FILES);
?>;
</script>
After which _arrayFromPhp would contain a representation of $_FILES in javascript.
Note
If you want to somehow work with previously uploaded files in your javascript environment, you should first handle the upload in PHP itself (where $_FILES comes to play) and then apply something like the aforementioned solution to get your information from PHP into your javascript environment.
Please also note that $_FILES will only contain anything if the script is being called directly through the upload process. If you upload files and then reload the page (for example), $_FILES will be empty.
Hint
In case you are using a conventional upload form, please make sure that your form is set to the correct encoding type (by setting the attribute enctype):
<form method="post" enctype="multipart/form-data">
</form>
The $_FILES variable is specific to PHP and not JS. If you want to use JS you will have some restrictions to deal with. You may check out some HTML5 file handling at this link http://www.html5rocks.com/en/features/file_access
Let me just expand on the difference between PHP and Javascript (in this context).
This is a simplified flow;
Client (your or someone else's browser) requests the website at myURL.com. This requests hits your server (LAMP stack for instance) and Apache routes this request to the right place, and PHP is executed on your server and this generates HTML. But really, this "HTML" is just a plain string. PHP does not know what HTML is, or anything about it, and when you are echo-ing or printing etc HTML from PHP, PHP just thinks of it as a string.
PHP has the ability to interact with the database (M in LAMP for MySQL - in this imaginary case) as well as some server variables ($_SERVER and $_POST/GET). Once all the PHP executes and creates your HTML, it sends this HTML as a simple string to the client browser.
The browser gets this string and then it begins to interpret it as HTML. It reads the HTML and will start downloading your assets like javascript files, CSS files, images etc etc and begins to pull all this together. So your javascript file gets read and executed and you CSS begins to style the HTML. The Javascript can continue running on the client, or be triggered to run certain functions by certain events (clicking, timing, scrolling etc).
As you can see, the client has NO access to running PHP. All the PHP has run on the server, and returned a string. All the client does is execute Javascript, in simple terms.
Now as things get a bit more advanced you can start using AJAX. AJAX is a combination of technologies (Asynchronous JavaScript and XML) which is used to make requests to servers without reloading or redirecting the client to a new page. What this means is that you can have your client be at myURL.com and make an AJAX request to myURL.com/myAJAXHandler.php. The client stays at myURL.com, however the server basically sees it the client trying to access the myURL.com/myAJAXHandler.php page in the browser. The server does its normal thing, runs whatever PHP is at that address, and again, returns a simple string to the client. The client using Javascript gets this string and can do what it wants with it, which is usually updating the current page (still myURL.com) or any number of things.
This is a simplified explanation and I've left a lot of things out and generalised a lot but I'm just trying to give you a general idea of what happens.
Hope this helped.

PHP to JS: printing js variable (like PHP echo) compatible with AJAX responseText?

I'm using W3 Schools' AJAX PHP Example (http://www.w3schools.com/ajax/ajax_aspphp.asp) as the foundation for my guestlist web app that uses data stored in LocalStorage, rather than MySQL database, in order for users to be able to search while offline. Now I'm trying to finalize the search guest part.
This is how it works (and differs from the example above):
(index.php). Placing / mirroring all records from MySQL db into
javascript arrays
(index.php). Storing the above mentioned js arrays in LocalStorage
(index.php). By using the AJAX GET code used in the example,
sending the searched item to getData.html (a html file instead of
php file as W3 does)
(getData.html). Successfully getting the searched item through the
URL parameter
(getData.html). Looping through and matching values like in the
above example (code rewriten in javascript).
BUT here ends my success. The AJAX code is identical to the one in the above supplied example (except of course the reference to getData.html), and everything else seems to be working so I won't bother you with my entire code. In the example mentioned, at the very buttom of the PHP-file it says
//output the response
echo $response;
This is where javascript seems to be failing. I've desperately been trying to echo / print the response but for some reason, it doesn't get returned to index.php properly. The only way to force it to display at least something is to either use php echo, or simply just write plain html text somewhere in the getData document within the HTML tags. I've also tried getElementById('txtHint').innerHTML = "hello"; to see if it works but with no success.
The most obvious way to do this would be to simply replace echo $response with the equivalent in js:
document.write(response);
but whatever document.write prints, nothing's dipslayed. The div in which the "hint" is supposed to pop up is yet empty. I've googled solutions, different ways of printing js variables with no further success. Perhaps, document.write is not "compatible" with XML or AJAX responseText? There must be a simple solution to this. Hope you guys can help me out. Thanks!
php is of course a server-side language that emits a page and runs on your back end.
js is of course a client-side language that runs on the user's front end.
document.write() is the proper function for emitting client-side text; it runs at page load time. Example:
<b>My domain is: <script>document.write(document.domain);</script></b>
properly gives
My domain is: www.mydomain.com

Categories