I'm using JS and PHP to collect a rows of information from a MySQL DB. This is working fine until I'm adding code to get a PDF-blob in the same return.
var docs;
getMini = function() {
showMiniLoading();
var req = new XMLHttpRequest();
req.onload = function() {
console.log("GOT IT!");
var temp = JSON.parse(this.responseText);
docs = temp;
hideMiniLoading();
printAllMini();
};
req.open("get", "resources/php/newMini.php", true);
req.send();
console.log("SENT!");
}
showPDF = function(id) {
for (var i = 0; i < docs.length; i++) {
var object = docs[i];
if (object.id == id) {
console.log("Found it! :D " + i);
console.log("Content: " + object.pdf);
// MORE STUFF HERE
document.getElementById("pdf").innerHTML = '<object "data:application/pdf,' + object.pdf + '" type="application/pdf" width="100%" height="100%"> <p>Alternative text - include a link to the PDF!</p> </object>';
break;
}
}
}
<?php
session_start();
include_once 'maindb.php';
$mysqli = mysqli_connect($dbMain['host'], $dbMain['user'], $dbMain['pass'],
$dbMain['db'])
or die('Kunde inte ansluta till databasen:'.mysqli_error($Maincon));
if(!$result = $mysqli->query(
"SELECT tblDokument.ID, tblMail.inkommet,
tblDokument.datum, tblDokument.Moms, tblDokument.pris, tblDokument.Org,
tblVerifikat.verifikatNo, tblLevMallar.OrgNr, tblLevMallar.name,
tblDokumentSvg.svg, tblDokumentPdf.pdf
FROM tblDokument
LEFT OUTER JOIN tblVerifikat ON tblDokument.ID = tblVerifikat.ID
LEFT OUTER JOIN tblMail ON tblDokument.tblMail_ID = tblMail.ID
LEFT OUTER JOIN tblLevMallar ON tblDokument.orgnr = tblLevMallar.OrgNr
LEFT OUTER JOIN tblDokumentSvg ON tblDokument.ID = tblDokumentSvg.dokumentid
LEFT OUTER JOIN tblDokumentPdf ON tblDokument.ID = tblDokumentPdf.id
WHERE tblVerifikat.verifikatNo <> 'Makulerad'
ORDER BY tblDokument.ID"))
{
echo "VERYTHING IS BAD";
}
else {
$i = 0;
while ($row = $result->fetch_assoc()) {
$tempPDF = $row["pdf"];
$size = filesize($tempPDF);
header('Content-type: application/pdf');
header("Content-length: $size");
header('Content-Disposition: attachment; filename="new.pdf")');
$tempArray[$i] = array(
"id" => $row["ID"],
"arrived" => substr($row["inkommet"], 0, 10),
"booked" => $row["datum"],
"verification" => $row["verifikatNo"],
"org" => $row["name"],
"price" => $row["pris"],
"stax" => $row["Moms"],
"pic" => base64_encode($row["svg"]),
"pdf" => $tempPDF);
$i++;
}
// HEADER STUFF
$done = json_encode($tempArray);
$size = strlen($done);
header('Content-type: application/json');
header("Content-length: $size");
header('Connection: close');
echo $done;
}
$result->close();
$mysqli->close();
?>
I encode the result with JSON at the end, but whatever I do I end up with a column full of null-values, instead of the desired PDF-blob. I've also tried to encode the entire pdf with base64_encode(), but then I get an error that says:
Uncaught SyntaxError: Unexpected token <
.. in the console of my browser.
Actual question:
How do i send a PDF-blob together with some other information and encoded in JSON?
I've tried a lot of other threads but haven't seen a solution that works in this case :/
NOTE:
I am very now to PHP and any additional feedback about the efficiency of the code above is highly appreciated.
Related
It seems like Instagram has changed certain things, because I have tried several codes on my html website to show the amount of Instagram followers on a button, but nothing works.
I tried this:
<?php
$account='XXX';
$instagramsource=file_get_contents('https://instagram.com/' . $account);
preg_match_all('/"userInteractionCount":"(.*?)"/', $instagramsource, $count);
$followcount=$count[1][0];
echo "$account instagram account has $followcount followers";
?>
Also this
<?php
$otherPage = 'XXX';
$response = file_get_contents("https://www.instagram.com/$otherPage/?__a=1");
if ($response !== false) {
$data = json_decode($response, true);
if ($data !== null) {
$follows = $data['graphql']['user']['edge_follow']['count'];
$followedBy = $data['graphql']['user']['edge_followed_by']['count'];
echo $follows . ' and ' . $followedBy;
}
}
?>
And this ...
<?php
$url = "https://www.instagram.com/XXX";
$json = file_get_contents($url);
$obj = json_decode($json, true);
$content = $obj['query']['results']['script']['content'];
$content = str_replace("window._sharedData =", "", $content);
$content = str_replace(";", "", $content);
$content = trim($content);
$json = json_decode($content);
$instagram_follower_count = $json->entry_data->ProfilePage{0}->user->followed_by->count;
?>
And finally this:
<?php
$username = 'XXX';
$response = #file_get_contents( "https://www.instagram.com/$username/?__a=1" );
if ( $response !== false ) {
$data = json_decode( $response, true );
if ( $data !== null ) {
$follows = $data['graphql']['user']['edge_follow']['count'];
$followedBy = $data['graphql']['user']['edge_followed_by']['count'];
echo 'XXX follows:' . $follows . ' and is followed by: ' . $followedBy;
}
}
?>
None works.
Can anyone indicate what would work in 2021, please?
Thanks.
It's because the url https://www.instagram.com/$username/?__a=1 is redirecting to login page & giving u a html response
You can check it by echo $response
These posts will help you link1,link2
Instagram blocked access via __a=1 parameter since 2018-04-12. __a=1 must be replaced by JS and Ajax bypass. I've looked for an alternative solution. You can use javascript code inside php. For example:
async function instagramFollowers () {
const followers = []
try {
const userInfoSource = await Axios.get('https://www.instagram.com/123/')
const jsonObject = userInfoSource.data.match(/<script type="text\/javascript">window\._sharedData = (.*)<\/script>/)[1].slice(0, -1)
const userInfo = JSON.parse(jsonObject)
const mediaArray = userInfo.entry_data.ProfilePage[0].graphql.user.edge_owner_to_timeline_media.edges.splice(0, 10)
for (let media of mediaArray) {
const node = media.node
followers.push(node.thumbnail_src)
}
} catch (e) {
console.error('Unable to retrieve Followers. Reason: ' + e.toString())
}
return followers
}
Other helpful links: how to write javascript code inside php
https://code.tutsplus.com/tutorials/how-to-use-ajax-in-php-and-jquery--cms-32494
I have an empty test.php file,in that file, I've inserted data below shown.
This code is form controller. This trace data coming from UI using ajax.
Here my $trace array data like this :
array(
[0] => $test1 = "1,2,3,4,5,6,7";
[1] => $test2 = "1,2,3,4,7";
[2] => $test3 = "1,4,6,7,9,0";
)
This is coming from UI
$trace = $this->input->post('trace');
$viewsDir = 'C:/xampp/htdocs/project/application/views/html_v3/';
$fp = fopen($this->viewsDir.'test.php', 'w');
fwrite($fp, "<?php \n\n");
$i = 0;
if($trace){
foreach ($trace as $value) {
fwrite($fp, $trace[$i]."\n");
$i++;
}
}
fwrite($fp, "\n?>");
fclose($fp);
After inserted my data into test.php file then the file look like this:
<?php
$test1 = "1,2,3,4,5";
$test2 = "5,2,0,6,5";
$test3 = "4,8,9,7,1";
?>
Here, if once again I want to insert data into test.php file, my $trace array data like this:
aray(
[0] => $test1 = "9,9,9,9,9";
[1] => $test2 = "1,1,1,1,1";
[2] => $test4 = "1,2,6,7,8";
)
Here my query is how can I replace this ($trace)array variables if matched with test.php. If not matched it should be added to the test.php file.
Here my expected output is:
<?
$test1 = "9,9,9,9,9";
$test2 = "1,1,1,1,1";
$test3 = "4,8,9,7,1";
$test4 = "1,2,6,7,8";
?>
I tried like this,but i don't know how to compare my array($trace) and content of test.php
$file = $this->viewsDir.'test.php';
$contents = file_get_contents($file);
echo $contents; //i will get content of test.php based on this i have to replace or add
Please help me,
Thanks.
I'm not even sure I should help you with that. There is possibly something very wrong with your design if you're passing php code via POST and save it to a source file.
Anyways...
I'd declare helper function that 'parses' entry string line as key $trace1 and value "1,2,3,4,5" and adds it to array $arr
function addToTrace(&$arr, $entry) {
$entry = trim($entry);
if(substr($entry, 0, 1) == "$") {
$elements = explode("=", $entry);
if(count($elements) !== 2) {
return false;
}
$elements = array_map('trim', $elements);
$arr[$elements[0]] = $elements[1];
return true;
}
return false;
}
After that it's only a matter of reading the file first, adding all entries to new array $currTrace
$currTrace = [];
$fp = fopen($this->viewsDir . 'test.php', 'r');
if($fp) {
while (!feof($fp)) {
$line = fgets($fp);
addToTrace($currTrace, $line);
}
fclose($fp);
}
than adding new trace from post (ovewriting matching keys):
if($trace){
foreach ($trace as $value) {
addToTrace($currTrace, $value);
}
}
and saving $currTrace to file:
$fp = fopen($this->viewsDir . 'test.php', 'w');
fwrite($fp, "<?php \n\n");
foreach($currTrace as $key => $value) {
fwrite($fp, $key . " = " . $value . "\n");
}
fclose($fp);
i have 2 file tst.html and tst.php
tst.html body is
<form>
<input id="search" type="text" size="30" onkeyup="showresult(this.value)" >
<div id="suggest"></div>
</form>
<script>
function showresult(val){
if(val.trim() == ""){
}else{
var xttp = new XMLHttpRequest() ;
xttp.onreadystatechange = function () {
var s = xttp.responseText ;
if(s.match("zerorow")){
document.getElementById("suggest").innerHTML = "zero" ;
}else {
try {
window.alert(s) ;
var arr = JSON.parse(s) ;
}
catch(err) {
document.getElementById("suggest").innerHTML = err.message;
}
}
};
xttp.open("POST" , "tst.php" ,true) ;
xttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded") ;
xttp.send("val="+val) ;
}
}
and tst.php
<?php
$servername = "localhost";
$dbusername = "mamad";
$dbpassword = "";
$dbname = "t1" ;
// Create connection
$conn = mysqli_connect($servername, $dbusername, $dbpassword , $dbname);
if (!$conn) {
die("Connection failedddddddddd: " . mysqli_connect_error());
}else{
$val = $_POST["val"] ;
$sql = "SELECT tag FROM tags WHERE tag LIKE '$val%'";
$result = mysqli_query($conn, $sql);
if($result){
if(mysqli_num_rows($result) > 0){
$arr = mysqli_fetch_all($result , MYSQLI_NUM) ;
echo json_encode($arr) ;
}else{
echo "zerorow" ;
}
}else{
echo die("faileddd " . mysqli_connect_error());
}
}
?>
assume in my database i have two record tag1 and tag2 in tag column
and
$arr = mysqli_fetch_all($result , MYSQLI_NUM) ;
json_encode($arr) ;
if you input t alphabet in input field tst.php
pass a 2 dimensional array as string like this [["tag1"],["tag2"]]
but
var arr = JSON.parse(s) ;
throw a syntax error with JSON.parse: unexpected end of data at line 1 column 1 of the JSON data message
and one more question i just want want column of data of table in my database is there any function that do it and give one dimensional array ?
sorry if it become long question .
The onreadystatechange event fires on every state change, not only if the request is finished and the result is returned.
You have to add some checks to make it work:
The readyState must be in status DONE, and
the http status must be 200
In code that looks like this:
xttp.onreadystatechange = function () {
if(xhr.readyState === XMLHttpRequest.DONE && xttp.status === 200) {
var s = xttp.responseText ;
if(s.match("zerorow")){
document.getElementById("suggest").innerHTML = "zero" ;
} else {
try {
window.alert(s) ;
var arr = JSON.parse(s) ;
} catch(err) {
document.getElementById("suggest").innerHTML = err.message;
}
}
}
};
Hint: Better use only one return type. In your case JSON. In your code your mixing up different content types. That's bad style
Furthermore your sql is attackable with sql injections. This is an security and safty issue
I have an input box in html. The input searches an database through ajax and return the results in front-end. The problem is that I don't get the result from PHP. I don't know what I did wrong, so I hope you guys have a better understanding from me.
HTML
<body onload="AjaxFindPerson()">
.....
</body>
JS
var xmlHttp = createXmlHttpRequestObject();
function AjaxFindPerson() {
if ((xmlHttp.readyState == 0 || xmlHttp.readyState == 4) && document.getElementById("PersonSearchInput").value != "") {
person = encodeURIComponent(document.getElementById("PersonSearchInput").value);
xmlHttp.open("GET", "../lib/search.php?email=" + person, true);
xmlHttp.onreadystatechange = handleServerResponse;
xmlHttp.send(null);
}
else {
document.getElementById('Label-Result').innerHTML = "";
document.getElementById('UserNameSearchResult').innerHTML = "";
$('#add-person-btn').attr("disabled", "disabled");
setTimeout('AjaxFindPerson()', 1000);
}
}
function handleServerResponse() {
if (xmlHttp.readyState == 4 ) {
if (xmlHttp.status == 200) {
xmlResponse = xmlHttp.responseXML;
xmlDocumentElement = xmlResponse.documentElement;
result = xmlDocumentElement.firstChild.data;
if (result[0] != false) {
document.getElementById('Label-Result').innerHTML = result[1];
document.getElementById('UserNameSearchResult').innerHTML = result[0];
$('#add-person-btn').removeAttr("disabled", "disabled");
}
else {
document.getElementById('Label-Result').innerHTML = result[1];
}
setTimeout('AjaxFindPerson()', 1000);
}
else {
alert('Somenthing went wrong when tried to get data from server'+ xmlHttp.readyState);
}
}
}
PHP
<?php
header('Content-Type: text/xml');
echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
session_start();
define("DB_HOST", 'mysql6.000webhost.com');
define("DB_USER", '');
define("DB_PASSWORD", '');
define("DB_DATABSE", '');
echo '<response>';
$email = $_GET['email'];
$conn = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
mysql_select_db(DB_DATABSE, $conn);
$sq = mysql_query("SELECT UserEmail FROM Users");
$UserInfo = array();
while ($row = mysql_fetch_array($sq, MYSQL_ASSOC)) {
$UserInfo[] = $row['UserEmail'];
}
if (in_array($email, $UserInfo)) {
$result = mysql_query("SELECT UserName FROM Users WHERE UserEmail = '".$email."'");
$row = mysql_fetch_row($result);
$returnRes = array($row[0], "We found results"); //row[0] holds the UserN
echo $returnRes;
}
else {
$returnRes = array(false, "We couldn't find results");
echo $returnRes;
}
echo '</response>';
?>
If we check the php-xml file alone will see the image bellow :
Do I need to pass the values to xml-php with another way?
UPDATE 1 in PHP
I manage to found a way to return the data correctly. Here are the update 'touch'
header('Content-Type: application/json');
and
if (in_array($email, $UserInfo)) {
$result = mysql_query("SELECT UserName FROM Users WHERE UserEmail = '".$email."'");
$row = mysql_fetch_row($result);
echo json_encode(array( 'found' => $row[0], 'msg' => "We found results"));
}
else {
echo json_encode(array( 'found' => null, 'msg' => "We couldn't find results"));
}
The problem now is how to manipulate the js file to handle the return array. I made a try but it didn't worked:
result = xmlDocumentElement.firstChild.data;
if (result['found'] != null) {
document.getElementById('Label-Result').innerHTML = result['msg'];
document.getElementById('UserNameSearchResult').innerHTML = result['found'];
$('#add-person-btn').removeAttr("disabled");
}
else {
document.getElementById('Label-Result').innerHTML = result['msg'];
}
**UPDATE 2 WORKING JS **
I figure out how to retrieve the data from PHP.
xmlResponse = xmlHttp.responseXML;
xmlDocumentElement = xmlResponse.documentElement;
var result = JSON.parse(xmlDocumentElement.firstChild.data);
if (result['found'] != null) {
document.getElementById('Label-Result').innerHTML = result['msg'];
document.getElementById('UserNameSearchResult').innerHTML = result['found'];
$('#add-person-btn').removeAttr("disabled");
}
else {
document.getElementById('Label-Result').innerHTML = result['msg'];
}
NOW ALL THE CODE IS WORKING! THANK YOU VERY MUCH GUYS!
+1 to all of you!
Four things :
Usage of send(null) doesn't seems to be right, just don't pass null in it.
Second one is timeout method. Instead the way you are using it, you can call it in the callback function or instead of string use the name at the function call.
The usage to remove the attribute is also wrong. It is currently using a set method as you have supplied a second argument. The remove attribute method only takes a attribute name.
I would rather suggest you to set a header for the application/json and use json_encode() method to return data.
For printing an array, you can either use json_encode(), or do somehow else transform your array into a string.
If we were to ignore the white elephant in the room and gloss over the use of mysql_* functions then a slightly different approach
<?php
session_start();
define('DB_HOST', 'mysql6.000webhost.com');
define('DB_USER', '');
define('DB_PASSWORD', '');
define('DB_DATABASE', '');
$dom=new DOMDocument('1.0','utf-8');
$root=$dom->createElement('response');
$dom->appendChild( $root );
if( $_SERVER['REQUEST_METHOD']=='GET' && isset( $_GET['email'] ) ){
/* Basic filtering IF mysql_* functions are used! */
$email = trim( strip_tags( filter_input( INPUT_GET, 'email', FILTER_SANITIZE_EMAIL ) ) );
$conn = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
mysql_select_db( DB_DATABASE, $conn ) or die('error: database connection failed');
/* By the looks of the original there should be no need for two queries and then an array lookup */
$result = mysql_query("SELECT `UserName` FROM `Users` WHERE `UserEmail` = '".$email."';");
/* If there are results, add nodes to the dom object */
if( mysql_num_rows( $result ) > 0 ){
while( $rs=mysql_fetch_object( $result ) ){
$root->appendChild( $dom->createElement( 'user', $rs->UserName ) );
}
} else {
/* Otherwise add error message */
$root->appendChild( $dom->createElement( 'error', 'We couldn\'t find any results!' ) );
}
}
/* Send the xml back to the js client */
header('Content-Type: text/xml');
$xml=$dom->saveXML();
$dom=null;
exit( $xml );
?>
I am developing a smart tv app that plays live streams. App itself works fine, when i provide a valid xml playlist to it.
But when i use php to generate xml file (wich also generates fine), it doesnt work.
I get an error:
TypeError: 'null' is not an object (evaluating 'this.XHRObj.responseXML.documentElement')
Here is my php file that generates videoList.xml, it works 100%.
In short words, this script checks if MAC address in database, and if it is, then it writes videoList.xml with walid live streaming links.
SamsungAPI.php
<?php
$MAC = $_GET['MAC'];
require_once('../config.php');
//Remove brackets form array
$_INFO = preg_replace('/[{}]/', '', $_INFO);
$mysqli = new mysqli($_INFO['host'], $_INFO['db_user'], $_INFO['db_pass'], $_INFO['db_name']);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$sql="SELECT * FROM users WHERE admin_notes = '$MAC' ";
$rs=$mysqli->query($sql);
$rows=mysqli_num_rows($rs);
if ($rows == 1) {
//MAC FOUND
$row = mysqli_fetch_array($rs);
$username = $row['username'];
$password = $row['password'];
$file = "videoList.xml";
$txt_file = file_get_contents('http://' . $_SERVER['HTTP_HOST'] . '/get.php?type=starlivev3&username=' . $username . '&password=' . $password . '&output=hls');
$rows = explode("\n", $txt_file);
if(empty($rows[count($rows)-1])) {
unset($rows[count($rows)-1]);
$rows=array_map('trim',$rows);
}
$handle = fopen($file, "w+") or die('Could not open file');
fwrite($handle, "<?xml version=\"1.0\"?>"."\n");
fwrite($handle, "<rss version=\"2.0\">"."\n");
fwrite($handle, "<channel>"."\n");
foreach($rows as $row => $data)
{
//get row data
$row_data = explode(',', $data);
//replace _ with spaces
$row_data[0] = str_replace('_', ' ', $row_data[0]);
//generate playlist content
fwrite($handle, "<item>"."\n");
fwrite($handle, "<title>{$row_data[0]}</title>"."\n");
fwrite($handle, "<link>{$row_data[1]}</link>"."\n");
fwrite($handle, "<description> Reserved for EPG </description>"."\n");
fwrite($handle, "</item>"."\n");
}
fwrite($handle, "</channel>"."\n");
fwrite($handle, "</rss>");
fclose($handle);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
} else {
//MAC NOT FOUND
echo "MAC NOT FOUND";
}
mysqli_close($mysqli); // Closing Connection
?>
Then in samsung smart tv videoplayer app, i have xml parser like this:
Server.js
var Server =
{
/* Callback function to be set by client */
dataReceivedCallback : null,
XHRObj : null,
url : "http://myvalidhost.com/samsungAPI.php?MAC=02000027000b"
}
Server.init = function()
{
var success = true;
if (this.XHRObj)
{
this.XHRObj.destroy(); // Save memory
this.XHRObj = null;
}
return success;
}
Server.fetchVideoList = function()
{
if (this.XHRObj == null)
{
this.XHRObj = new XMLHttpRequest();
}
if (this.XHRObj)
{
this.XHRObj.onreadystatechange = function()
{
if (Server.XHRObj.readyState == 4)
{
Server.createVideoList();
}
}
this.XHRObj.open("GET", this.url, true);
this.XHRObj.send(null);
}
else
{
alert("Failed to create XHR");
}
}
Server.createVideoList = function()
{
if (this.XHRObj.status != 200)
{
Display.status("XML Server Error " + this.XHRObj.status);
}
else
{
var xmlElement = this.XHRObj.responseXML.documentElement;
if (!xmlElement)
{
alert("Failed to get valid XML");
}
else
{
// Parse RSS
// Get all "item" elements
var items = xmlElement.getElementsByTagName("item");
var videoNames = [ ];
var videoURLs = [ ];
var videoDescriptions = [ ];
for (var index = 0; index < items.length; index++)
{
var titleElement = items[index].getElementsByTagName("title")[0];
var descriptionElement = items[index].getElementsByTagName("description")[0];
var linkElement = items[index].getElementsByTagName("link")[0];
if (titleElement && descriptionElement && linkElement)
{
videoNames[index] = titleElement.firstChild.data;
if(linkElement.firstChild.data.substring(0,4) !="http"){
alert("asdasdasd "+linkElement.firstChild.data.substring(0,4));
var rootPath = window.location.href.substring(0, location.href.lastIndexOf("/")+1);
var Abs_path = unescape(rootPath).split("file://")[1]+linkElement.firstChild.data;
videoURLs[index] = Abs_path;
}
else{
videoURLs[index] = linkElement.firstChild.data;
}
videoDescriptions[index] = descriptionElement.firstChild.data;
}
}
Data.setVideoNames(videoNames);
Data.setVideoURLs(videoURLs);
Data.setVideoDescriptions(videoDescriptions);
if (this.dataReceivedCallback)
{
this.dataReceivedCallback(); /* Notify all data is received and stored */
}
}
}
}
Does anyone have any idea why doesnt it accept my generated xml file?
Regards
M
I figured it out, in php headers content type was wrong.
Changed
header('Content-Type: application/octet-stream');
to
header('Content-Type: application/xml');
Now it works perfect!