How do I grab JSON output with PHP - javascript

Ok, this is my first try with TwitchAPI. When I make the request, I get:
{"follows":[{"created_at":"2015-04-28T01:04:33Z","_links":{"self":"https://api.twitch.tv/kraken/users/chaoticaura/follows/channels/giygaslp"},"notifications":true,"user":{"_id":54441701,"name":"chaoticaura","created_at":"2014-01-05T01:06:19Z","updated_at":"2015-04-28T14:18:50Z","_links":{"self":"https://api.twitch.tv/kraken/users/chaoticaura"},"display_name":"ChaoticAura","logo":"http://static-cdn.jtvnw.net/jtv_user_pictures/chaoticaura-profile_image-3b6a888d174153f6-300x300.jpeg","bio":"Welcome to the House of Gaming/Crazy/Stupid ChaoticAura","type":"user"}},{"created_at":"2014-08-10T06:25:10Z","_links":{"self":"https://api.twitch.tv/kraken/users/phoenix089/follows/channels/giygaslp"},"notifications":true,"user":{"_id":31004257,"name":"phoenix089","created_at":"2012-06-03T01:41:37Z","updated_at":"2015-04-22T19:58:28Z","_links":{"self":"https://api.twitch.tv/kraken/users/phoenix089"},"display_name":"phoenix089","logo":null,"bio":null,"type":"user"}},{"created_at":"2014-05-10T17:41:05Z","_links":{"self":"https://api.twitch.tv/kraken/users/monanniverse/follows/channels/giygaslp"},"notifications":true,"user":{"_id":30041264,"name":"monanniverse","created_at":"2012-04-25T10:45:21Z","updated_at":"2015-04-17T18:58:05Z","_links":{"self":"https://api.twitch.tv/kraken/users/monanniverse"},"display_name":"Monanniverse","logo":null,"bio":null,"type":"user"}},{"created_at":"2013-04-25T01:10:57Z","_links":{"self":"https://api.twitch.tv/kraken/users/princess_sarahkat/follows/channels/giygaslp"},"notifications":true,"user":{"_id":27411850,"name":"princess_sarahkat","created_at":"2012-01-13T23:45:04Z","updated_at":"2014-08-01T17:49:47Z","_links":{"self":"https://api.twitch.tv/kraken/users/princess_sarahkat"},"display_name":"Princess_SarahKat","logo":"http://static-cdn.jtvnw.net/jtv_user_pictures/princess_sarahkat-profile_image-5b554c88c6eb89a9-300x300.png","bio":null,"type":"user"}},{"created_at":"2012-12-04T13:43:15Z","_links":{"self":"https://api.twitch.tv/kraken/users/thedaredevil717/follows/channels/giygaslp"},"notifications":true,"user":{"_id":38212339,"name":"thedaredevil717","created_at":"2012-12-04T13:41:17Z","updated_at":"2013-09-27T12:38:53Z","_links":{"self":"https://api.twitch.tv/kraken/users/thedaredevil717"},"display_name":"Thedaredevil717","logo":null,"bio":null,"type":"user"}}],"_total":5,"_links":{"self":"https://api.twitch.tv/kraken/channels/giygaslp/follows?direction=DESC&limit=25&offset=0","next":"https://api.twitch.tv/kraken/channels/giygaslp/follows?direction=DESC&limit=25&offset=25"}}
I'm told that this is a JSON Response. How do I take this information, and use it with variables in PHP?
I've made some attempts that failed, here is the code:
<html>
<?php $json=json_decode(file_get_contents( "https://api.twitch.tv/kraken/channels/giygaslp/follows?limit=1")); $currentFollower=0 ; $currentPage=0 ; $resultsPerPage=5 ; $tableHtml=<
<<TABLE <div id="page-number-%s" style="%s">
<table>
<tr>
<th>Username:</th>
<th>Follow Date:</th>
<th>Type:</th>
</tr>
%s
</table>
</div>
TABLE; $rowHtml =
<<<ROW <tr>
<td>%s
</td>
<td>%s</td>
<td>%s</td>
</tr>
ROW; $html = ""; $rows = ""; foreach ($json->follows as $follow) { if ($currentFollower % $resultsPerPage == 0 && $currentFollower> 0) { $style = $currentPage === 0 ? '' : 'display:none'; $html .= sprintf($tableHtml, $currentPage, $style, $rows); $rows
= ""; $currentPage++; } $rows .= sprintf( $rowHtml, $follow->user->_links->self, $follow->user->name . ' (' . $currentFollower . ')', $follow->user->created_at, $follow->user->type ); $currentFollower++; } $html .=
<<<BUTTONS <button onclick="previousPage()">previous</button>
<button onclick="nextPage()">next</button>
BUTTONS; $javascript =
<<<JS <script>
var currentPage = 0; function previousPage() { if(currentPage > 0) { document.getElementById('page-number-'+currentPage).style.display = 'none'; currentPage--; document.getElementById('page-number-'+currentPage).style.display = ''; } }; function nextPage()
{ if(currentPage
< {$currentPage} - 1) { document.getElementById( 'page-number-'+currentPage).style.display='none' ; currentPage++; document.getElementById( 'page-number-'+currentPage).style.display='' ; } }; </script>
JS; echo $javascript.$html; ?>
</html>
That doesn't work though... any ideas?
Edit:
Im using this at the moment for testing
<html>
<script>
<? php
$json = json_decode(file_get_contents("https://api.twitch.tv/kraken/channels/giygaslp/follows?limit=25"), true);
print $json['follows'];
var_dump($json['follows']) ?>
</script>
</html>

PHP's json_decode is a bit confusing. It returns an stdClass. Add the true option to get a regular PHP associative array.
$json = json_decode(file_get_contents( "http://myurl.com"), true);
var_dump($json['follows']); //var_dump is print for arrays
I've found that sometimes when using stdClasses, you have to use the key as a string:
$json->{'follows'}
Test your code at PhpFiddle

Look at this example Parsing JSON object in PHP using json_decode
and here is a way to parse it.
var_dump(json_decode($json));
var_dump(json_decode($json, true));
?>

You can convert that JSON data to an array which you can easily use with PHP. To do this use PHP's json_decode() function.
$decodedJSON = json_decode($JSON, true);
It's important you pass in true as the second parameter otherwise you will not get an array back.
Now that you have an array you can access elements from that JSON data in that array. For example:
$decodedJSON[key]
In the above example, key can be any key that was in the JSON data we converted and it will return whatever value belongs to that key.

Related

PHP 5.4.16 DOMDocument removes parts of Javascript

I try to load an HTML page from a remote server into a PHP script, which should manipulate the HTML with the DOMDocument class. But I have seen, that the DOMDocument class removes some parts of the Javascript, which comes with the HTML page. There are some things like:
<script type="text/javascript">
//...
function printJSPage() {
var printwin=window.open('','haha','top=100,left=100,width=800,height=600');
printwin.document.writeln(' <table border="0" cellspacing="5" cellpadding="0" width="100%">');
printwin.document.writeln(' <tr>');
printwin.document.writeln(' <td align="left" valign="bottom">');
//...
printwin.document.writeln('</td>');
//...
}
</script>
But the DOMDocument changes i.e. the line
printwin.document.writeln('</td>');
to
printwin.document.writeln(' ');
and also a lot of others things (i.e. the last script tag is no longer there. As the result I get a complete destroyed page, which I cannot send further.
So I think, DOMDocument has problems with the HTML tags within the Javascript code and tries to correct the code, to produce a well-formed document. Can I prevent the Javascript parsing within DOMDocument?
The PHP code fragment is:
$stdin = file_get_contents('php://stdin');
$dom = new \DOMDocument();
#$dom->loadHTML($stdin);
return $dom->saveHTML(); // will produce wrong HTML
//return $stdin; // will produce correct HTML
I have stored both HTML versions and have compared both with Meld.
I also have tested
#$dom->loadXML($stdin);
return $dom->saveHTML();
but I don't get any things back from the object.
Here's a hack that might be helpful. The idea is to replace the script contents with a string that's guaranteed to be valid HTML and unique then replace it back.
It replaces all contents inside script tags with the MD5 of those contents and then replaces them back.
$scriptContainer = [];
$str = preg_replace_callback ("#<script([^>]*)>(.*?)</script>#s", function ($matches) use (&$scriptContainer) {
$scriptContainer[md5($matches[2])] = $matches[2];
return "<script".$matches[1].">".md5($matches[2])."</script>";
}, $str);
$dom = new \DOMDocument();
#$dom->loadHTML($str);
$final = strtr($dom->saveHTML(), $scriptContainer);
Here strtr is just convenient due to the way the array is formatted, using str_replace(array_keys($scriptContainer), $scriptContainer, $dom->saveHTML()) would also work.
I find it very suprising that PHP does not properly parse HTML content. It seems to instead be parsing XML content (wrongly so as well because CDATA content is parsed instead of being treated literally). However it is what it is and if you want a real document parser then you should probably look into a Node.js solution with jsdom
If you have a <script> within a <script>, the following (not so smart) solution will handle that. There is still a problem: if the <script> tags are not balanced, the solution will not work. This could occur, if your Javascript uses String.fromCharCode to print the String </script>.
$scriptContainer = array();
function getPosition($tag) {
return $tag[0][1];
}
function getContent($tag) {
return $tag[0][0];
}
function isStart($tag) {
$x = getContent($tag);
return ($x[0].$x[1] === "<s");
}
function isEnd($tag) {
$x = getContent($tag);
return ($x[0].$x[1] === "</");
}
function mask($str, $scripts) {
global $scriptContainer;
$res = "";
$start = null;
$stop = null;
$idx = 0;
$count = 0;
foreach ($scripts as $tag) {
if (isStart($tag)) {
$count++;
$start = ($start === null) ? $tag : $start;
}
if (isEnd($tag)) {
$count--;
$stop = ($count == 0) ? $tag : $stop;
}
if ($start !== null && $stop !== null) {
$res .= substr($str, $idx, getPosition($start) - $idx);
$res .= getContent($start);
$code = substr($str, getPosition($start) + strlen(getContent($start)), getPosition($stop) - getPosition($start) - strlen(getContent($start)));
$hash = md5($code);
$res .= $hash;
$res .= getContent($stop);
$scriptContainer[$hash] = $code;
$idx = getPosition($stop) + strlen(getContent($stop));
$start = null;
$stop = null;
}
}
$res .= substr($str, $idx);
return $res;
}
preg_match_all("#\<script[^\>]*\>|\<\/script\>#s", $html, $scripts, PREG_OFFSET_CAPTURE|PREG_SET_ORDER);
$html = mask($html, $scripts);
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHTML($html);
libxml_use_internal_errors(false);
// handle some things within DOM
echo strtr($dom->saveHTML(), $scriptContainer);
If you replace the "script" String within the preg_match_all with "style" you can also mask the CSS styles, which can contain tag names too (i.e. within comments).

passing array of string from php to html

I want to tranform a php array of string into html. My php and html code are in the same page.
I have $myvar that hold my array of string. I pass $myvar with POST and insert it to $ba.
My code needs to print on html page 3 line (in while loop).
But when I pass the $be, it writes me error message: "Notice: Undefined index: myvar" (in php code)
What do I need to repair so that my code prints to my screen all the 3 lines that I get from php?
my code:(php)
foreach ($docres as $key=>$filename) {
$counter = 0;
$file = $filename +1;
$handle = fopen($dir."/".$file.'.txt',"r");
if($handle)
{
while($counter < 3)
{
$myvar[]=fgets($handle);
$counter++;
}
}
}
$ba = implode("", $myvar);
my html code:
<form action="" method="POST">
<center>
<h1> My Search Engine </h1>
<input type = 'text' size='90' value='' name = 'search' > <br>
<input type = 'submit' name = 'submit' value = 'Search source code'>
</center>
</form >
<p> <?php echo $ba ?> </p>
Simply echo the mysql query on a function and call it on HTML as follows:
UPDATE: 3rd column will be an image wich route are stored on database, and 4th col will be an image eich only the name was stored on database (because we know the full route) as example:
<?php
function printOnHtml(){
include ("connection.php");
$sql = "SELECT * FROM foo;"
if ($result = connection()->query($sql)){
$rs = $result->fetch_array(MYSQLI_NUM);
while ($rs[0] != ''){
echo "first column: ".$rs[0]." second column: ".$rs[1]." image with full route on database: <img src='".$rs[2]."' alt=''> <br> if only the img name is stored cuz we know the route: <img src='img_route/".$rs[3]."' alt=''>";
$rs = $result->fetch_array(MYSQLI_NUM);
}
}
}
Then on HTML
<html>
blablabla
<body>
blablabla
<?php
printOnHtml();
?>
blablabla
</body>
</html>
Note that it have to be a .php file to call the php function (for example index.php)
I paste the connection php script i use in order if you need it:
<?php
function connection(){
if($mysqli = new MySQLi("localhost","user","password","database_name")) echo "OK"; else echo "KO";
mysqli_set_charset($mysqli, "utf8");
return $mysqli;
}
?>
i did it with mysqli fetch array, but you can do the same using fetch assoc if you want.
UPDATE2: If you stubborness makes you follow using a txt to store data (wich, if increase will fail when you get a some thousands line txt), modify this on your code:
$myvar='';
foreach ($docres as $key=>$filename) {
$counter = 0;
$file = $filename +1;
$handle = fopen($dir."/".$file.'.txt',"r");
if($handle)
{
while($counter < 3)
{
if(isset($myvar)){
$myvar=fgets($handle);
}
$counter++;
}
}
}
and i'm supposing that you declared $dir, $file and other vars properly.
You NEVER have to use vars without declaring it (as NULL at least). You only can do this if you ensured 100% that this var will get a value at this point.
You have to convert the array to string in a correct way using implode and <br> as a separator
Then just print it using php tags (as you are using both at the same page ) you can access the variable direct and print it using <?= $ba ?> or <?php echo $ba ; ?>
Code will be :
<?php
foreach ($docres as $key=>$filename) {
$counter = 0;
$file = $filename +1;
$handle = fopen($dir."/".$file.'.txt',"r");
if($handle)
{
while($counter < 3)
{
$myvar[]=fgets($handle);
$counter++;
}
}
}
$ba = implode("<br>", $myvar);
?>
<form action="" method="POST">
<center>
<h1> My Search Engine </h1>
<input type = 'text' size='90' value='' name = 'search' > <br>
<input type = 'submit' name = 'submit' value = 'Search source code'>
</center>
</form >
<p id="deatiles"> <?= $ba ?> </p>

PHP `file_get_contents()` output pass to JavaScript and calculate length

I want to pass the output from PHP's file_get_contents() to JavaScript and calculate its length. Everything ok but when passing the variable JavaScript evaluates it as HTML code, so I have to use PHP's json_encode() to keep it "sane" but this way the string length from JavaScript will be different from the one in PHP. Using JS's JSON.parse() doesn't help because again the HTML code gets interpreted. Any idea how can I achieve the same evaluated data length?
EDIT: Basically I need to count all the characters in the page source, that includes tags and special characters. To have the same output computed in JS like the one i get in PHP's strlen($url_data).
EDIT 2: I thought about doing bin2hex() on the $url_data then reconvert in JS and check the length. Would be that reliable?
Here is what I did so far:
<?php
ini_set('display_erros', -1);
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['urlinput']) && !filter_var($_POST['urlinput'], FILTER_VALIDATE_URL) === false) {
$url = filter_var($_POST['urlinput'], FILTER_SANITIZE_URL);
$url_data = #file_get_contents($url);
$js_url_data = json_encode($url_data);
//$url_src = htmlspecialchars($url, ENT_IGNORE);
$url_data_len = mb_strlen($url_data);
$url_src = strip_tags($url_data);
echo '<ul id="resultList">';
echo "<li>The following page contains " . $url_data_len . " characters</li>";
echo "<li>Page URL: " . $_POST['urlinput'] . "</li>";
echo "<li>Page title: " . page_title($url_data) . "</li>";
echo "<li>Protocol: " . parse_url($url, PHP_URL_SCHEME) . "</li>";
echo "<li>Host: " . parse_url($url, PHP_URL_HOST) . "</li>";
echo "</ul>";
//var_dump($url_src);
} else {
$error = "URL is not valid!";
}
}
function page_title($str) {
$matches = array();
if (preg_match('/<title>(.*?)<\/title>/i', $str, $matches)) {
return $matches[1];
}
else {
return null;
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PHP file_get_contents()</title>
</head>
<body>
<div class="url_class">
<form id="getsrc" method="post">
<input style="width: 300px;" type="text" name="urlinput" id="urlinput" placeholder="URL">
<input type="submit" name="submit" value="Get SRC">
</form>
</div>
<textarea rows="20" cols="50">
<?php
if (!empty($url_src)) {
echo $url_src;
}
?>
</textarea>
<?php echo '<br><span style="color:red">' . $error . '<span>'; ?>
<?php
if (!empty($js_url_data)) {
$script = <<<EOT
<script>
var url_data = $js_url_data;
var node = document.createElement("li");
var textnode = document.createTextNode("JavaScript page characters: " + url_data.length);
node.appendChild(textnode);
document.getElementById("resultList").appendChild(node);
</script>
EOT;
echo $script;
}
?>
</body>
</html>
Simply use the value calculated by php, it can be used within EOT block:
...
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['urlinput']) && !filter_var($_POST['urlinput'], FILTER_VALIDATE_URL) === false) {
...
$url_data = #file_get_contents($url);
$fileSize = strlen($url_data);
...
}
....
if (!empty($js_url_data)) {
$script = <<<EOT
<script>
...
var textnode = document.createTextNode("JavaScript page characters: " + $fileSize);
...
</script>
EOT;
echo $script;
Since no good answer, I would post my solution to my problem. The only way I could find was to hex-encode $url_data, pass it to JS, decode it and count the characters. For the pack() function I used the one ported in php.js.
...
$js_url_data = bin2hex($url_data);
...
if (!empty($js_url_data)) {
/* This is a good example when one is forced to use inline JS */
$script = <<<EOT
<script>
var url_data = "$js_url_data";
var url_data_len = pack('H*', url_data).length;
var node = document.createElement("li");
var textnode = document.createTextNode("JavaScript calculation page characters: " + url_data_len);
node.appendChild(textnode);
document.getElementById("resultList").appendChild(node);
</script>
EOT;
echo $script;
...

Simple PHP array to Javascript array

I have an array in php lets call it:
$nums = array(10,25,52,32,35,23);
I want to send it to my javascript function like this:
var nums=[10,25,52,32,35,23];
How can i do this?
(My javascript file name is "nums.js")
Edit:
nums.js is a javascript code. It changes the values of table in the html. But the values only exist in php. So i have to send the values to javascript.
PHP >= 5.2
The json_encode function is for this purpose:
<?php echo 'var nums=' . json_encode(array(10,25,52,32,35,23)) . ';'; ?>
Docs: http://php.net/json_encode
PHP < 5.2
If you can't use json_encode, take a look at this post for a way to define an equivalent.
As long as your javascript file is being parsed by PHP before being sent to the client, then this should work:
<?php echo "var nums=[" . implode(',', $nums) . "];"; ?>
Just json_encode() the array and then output it as an array literal in javascript.
<?php
$nums = array(10,25,52,32,35,23);
$nums_json = json_encode($nums);
?>
<script type="text/javascript">
var nums = <?php echo $nums_json; ?>;
</script>
you can also use json_encode() but only possible from php 5.2
see more: http://us3.php.net/manual/fr/function.json-encode.php
or you can use this function:
function php2js ($var) {
    if (is_array($var)) {
        $res = "[";
        $array = array();
        foreach ($var as $a_var) {
            $array[] = php2js($a_var);
        }
        return "[" . join(",", $array) . "]";
    }
    elseif (is_bool($var)) {
        return $var ? "true" : "false";
    }
    elseif (is_int($var) || is_integer($var) || is_double($var) || is_float($var)) {
        return $var;
    }
    elseif (is_string($var)) {
        return "\"" . addslashes(stripslashes($var)) . "\"";
    }
    return FALSE;
}

HTML Escaping/Encoding in Javascript/PHP

I have multiple pages of html code saved into a database. I want a file to be able to flip through each of these pages without reloading.
I created a PHP file to pull all the pages into a database.
The page shows the first page and navigation buttons.
There is also javascript to put all the other pages into an array so I can quickly switch pages.
var pages = new Array();
<?php foreach ($coursePages as $page): ?>
pages[pageCount] = "<?php echo ($page['body']) ?>";
pageCount++;
<?php endforeach ?>
My problem is creating the javascript array. How can I escape the data from the echo properly so it can eventually change the page content using the following:
$(document).ready(function() {
$('.navNext, .navPrevious').click(function({
if ($(this).hasClass('navNext')) {
page++;
if (page > pageCount) {
page = 0;
}
} else {
page--;
if (page < 0) {
page = 0;
}
}
$('.page').html(pages[page]);
}))
});
Anytime you send values dynamically from PHP to JavaScript, you can simply use json_encode(). It will always produce valid JavaScript and handle all data types. Example:
<script>
var a = <?php echo json_encode($var)?>;
</script>
you can use this function to escape js values:
function js_escape_string($str)
{
$str = str_replace("\\", "\\\\", strval($str));
$str = str_replace("'", "\\'", $str);
$str = str_replace("\r", "\\r", $str);
$str = str_replace("\n", "\\n", $str);
$str = str_replace("\t", "\\t", $str);
$str = str_replace("</script>", "</'+'script>", $str);
return $str;
}
NOTE: use single quote ' around JS values, like:
<script>
var a = '<?php echo js_escape_string(....); ?>';
</script>

Categories