I try to view image in browser that i take from mongodb. the image correctly saved and I can download it perfectly using genghis.php but whenever I tried to load this using my own code whether ny using getBytes() or getResource(), the result only return bytes data such as this:
HDR¿£Ðß$iUßoÛT>‰oR¤? XG‡ŠÅ¯US[¹ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü#ÙH§kk?ì<Ê»øÎí¾kktüqóÝ
Here is the code that I use to retrieve the image:
<?php
// Config
$dbhost = 'localhost';
$dbname = 'dbzuhra';
$colname = 'testData';
// Connect to test database
$m = new Mongo("mongodb://$dbhost");
$db = $m->$dbname;
$getGrid = $db->getGridFS();
$image = $getGrid->findOne(array('filename'=>'final_design.png'));
header('Content-type: image/png;');
$stream = $image->getResource();
while (!feof($stream)) {
echo fread($stream, 8192);
}
?>
Is there any explanation to why this happen?
Incorrect header:
header('Content-type: image/png;');
^--- don't put a semi-colon here
There is no image type image/png;. It's just image/png, and HTTP headers are delimited by line breaks, not semicolons.
Related
I got a pretty specific question. I'm accessing data via samba on distant server and I got no choice. To achieve that in php I use a php wrapper for smbclient from GitHub https://github.com/icewind1991/SMB. I got a piece of code that works to load the video and play it but the problem is that I want to be able to navigate through the timeline and for it to play as soon as there is data to be read.. I repeat that I can't access data any other way and I use that library for other parts of my website so I can't change it. Right now it reads all the data from the whole video before playing it and I can't use the slider to navigate through the timeline. There's my code sample with false authentication data for the samba access.
<?php
require('../../class/SMB-master/vendor/autoload.php');
$host = '0.0.0.0';
$user = 'user';
$workgroup = 'workgroup.lan';
$password = 'password';
$share = 'share/'.$_GET["filePath"].'';
$auth = new \Icewind\SMB\BasicAuth($user, $workgroup, $password);
$serverFactory = new \Icewind\SMB\ServerFactory();
$server = $serverFactory->createServer($host, $auth);
$share = $server->getShare($share);
//Reads PDF 4096 bytes by 4096 bytes until there is no more data to read if the format is pdf
if($_GET['openFile'] == 'PDF')
{
$charNumber = 20;
$result = bin2hex(random_bytes($charNumber));
header("Content-type:application/pdf");
header("Content-Disposition:inline;filename=".$result.".pdf");
$fh = $share->read($_GET['name']);
while ($data = fread($fh, 4096))
echo $data;
fclose($fh);
}
else{
//Reads video 4096 bytes by 4096 bytes until there is no more data to read if the format is video mp4
header("Content-type:video/mp4");
header("Content-Disposition:inline;filename=".$_GET['name']."");
$fh = $share->read($_GET['name']);
while ($data = fread($fh, 4096)){
echo $data;
}
fclose($fh);
}
I'm making a simple setup form where you are asked to enter your database credentials which are stored in another PHP file but when the user submits it the contents in the database credentials file are deleted and the file is just empty. I have tried debugging my code but still can't figure out what is causing the problem.
My database credentials file:
<?php
define("DATABASE_HOST", "{DB_HOST}");
define("DATABASE_USER", "{DB_USER}");
define("DATABASE_PASSWORD", "{DB_PASSWORD}");
define("DATABASE_DATABASE", "{DB_NAME}");
My code:
$databasehost = $_POST['databasehost'];
$databaseuser = $_POST['databaseuser'];
$databasepassword = $_POST['databasepassword'];
$databasename = $_POST['databasename'];
$searchF = array('{DB_HOST}','{DB_USER}','{DB_PASSWORD}','{DB_NAME}');
$replaceW = array($databasehost, $databaseuser, $databasepassword, $databasename);
$fh = fopen("../static/database.php", 'w');
$file = file_get_contents('../static/database.php');
$file = str_replace($searchF, $replaceW, $file);
fwrite($fh, $file);
fclose($fh, $file);
Thanks,
Nimetu.
You read the file with the call
$file = file_get_contents('../static/database.php');
after you have opened the file using w. Opening it for write will automatically blank the file. So change the order to
$file = file_get_contents('../static/database.php');
$fh = fopen("../static/database.php", 'w');
I'm trying to make a PHP page that queries a database, creates a CSV in the tmp folder then sends that csv to the browser to download, but the file that downloads contain only the last echo in the PHP script, not the file that is stored on the server (that file is saved on the server is perfect).
<?php
$db_host = "localhost"; //can be "localhost" for local development
$db_username = "root";
$db_password = "";
$db_name = "seinventory";
$link = mysqli_connect($db_host,$db_username,$db_password,$db_name) or die(mysqli_error($link));
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$softwareName = $_GET['soft'];
$result = mysqli_query($link,"SELECT * FROM `seinventory` WHERE software LIKE '%$softwareName%' or apps LIKE '%$softwareName%'");
$timeStamp = date('d.m.Y-h.i.s');
$csvFile = 'C:/xampp/htdocs/tmp/file.csv';
$new_csv = fopen($csvFile, 'w');
$headings = Array('PC Name','Software Name','Software Version');
fputcsv($new_csv, $headings);
while($row = mysqli_fetch_array($result))
{
$pcName = $row['pcName'];
$software = $row['software'];
$app = $row['apps'];
$softwareArray = explode(";", $software);
$appArray = explode(";", $app);
$multiArray = array_merge($softwareArray, $appArray);
foreach ( $multiArray as $value ) {
$singleSoftwareArray = explode(":", $value);
$softwareItem = $singleSoftwareArray[0];
$pcName = str_replace('.domain.local', '', $pcName);
if (stripos($softwareItem, $softwareName) !== false) {
$singleArray = Array($pcName, $singleSoftwareArray[0], $singleSoftwareArray[1]);
fputcsv($new_csv, $singleArray);
}
}
}
fclose($new_csv);
mysqli_close($link);
// tell the browser it's going to be a csv file
header('Content-Type: application/csv');
// tell the browser we want to save it instead of displaying it
header('Content-Disposition: attachment; filename="file.csv";');
//unlink($csvFile);
echo "<script>window.close();</script>";
I read somewhere I'm supposed to put exit; after the fclose to stop it writing to the file, but my file on the server is perfect somehow it's being changed during the download process.
You must echo the content of the CSV file to get the correct file. Remove the last echo from your code and replace it with this one.
echo file_get_contents('C:/xampp/htdocs/tmp/file.csv');
As you are storing the file locally you can also redirect the user to a file URL and it should trigger the download. You won't have to pass the content-disposition header if you do it. You have to remove lines providing Content-Type, Content-Disposition header, and last echo statement if you decide to do it this way.
header("Location: tmp/file.csv");
If you are creating the file just temporarily and removing it afterwards then I suggest you should store the data in memory and echo it afterwards.
<?php
$db_host = "localhost"; //can be "localhost" for local development
$db_username = "root";
$db_password = "";
$db_name = "seinventory";
$link = mysqli_connect($db_host,$db_username,$db_password,$db_name) or die(mysqli_error($link));
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$softwareName = $_GET['soft'];
$result = mysqli_query($link,"SELECT * FROM `seinventory` WHERE software LIKE '%$softwareName%' or apps LIKE '%$softwareName%'");
$timeStamp = date('d.m.Y-h.i.s');
$new_csv = fopen('php://memory', 'w+');
$headings = Array('PC Name','Software Name','Software Version');
fputcsv($new_csv, $headings);
while($row = mysqli_fetch_array($result))
{
$pcName = $row['pcName'];
$software = $row['software'];
$app = $row['apps'];
$softwareArray = explode(";", $software);
$appArray = explode(";", $app);
$multiArray = array_merge($softwareArray, $appArray);
foreach ( $multiArray as $value ) {
$singleSoftwareArray = explode(":", $value);
$softwareItem = $singleSoftwareArray[0];
$pcName = str_replace('.domain.local', '', $pcName);
if (stripos($softwareItem, $softwareName) !== false) {
$singleArray = Array($pcName, $singleSoftwareArray[0], $singleSoftwareArray[1]);
fputcsv($new_csv, $singleArray);
}
}
}
mysqli_close($link);
// tell the browser it's going to be a csv file
header('Content-Type: application/csv');
// tell the browser we want to save it instead of displaying it
header('Content-Disposition: attachment; filename="file.csv";');
// set the file pointer position back to 0
rewind($new_csv);
// echo all the contents from current file pointer position(In this case from start of the file)
echo stream_get_contents($new_csv);
I have searched the internet, and could not get any specific details about it.
The environment is Windows 8, WAMP , MONGODB
I am trying to design a webpage, which have 4 fields: Name,Contact,Device,Email. After an user hits the submit button, the data inserts in the MongoDb. All this works fine.
The issue starts when I try to write the inserted data in the csv file, as this is the requirement. I have tried MongoDB Export command in the cmd, and it works fine, but trying to call the same using exec function in the php script is proving to be futile.
I have tried with this also, by storing the command in a .bat file, and then calling the .bat file using the php's exec function, still, no effect
<?php
echo '<pre>';
// Outputs all the result of shellcommand "ls", and returns
// the last output line into $last_line. Stores the return value
// of the shell command in $retval.
exec("c:\WINDOWS\system32\cmd.exe /c START C:\wamp\bin\mongodb\mongodb-win32-x86_64-2008plus-2.4.3\conf\export.bat");
?>
I have enabled the checbox interaction with desktop in my WAMP server.
I don't need any specific help related with the coding, all I need is some direction on how to proceed ahead, as I know that I am missing something. Also, I reiterate, did not get anything specific on the Internet, hence, posting the question.
Kindly let me know on how to achieve this.
Thanks to everyone
The following may work
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');
$database = "DATABASE";
$colName = "COLLECTION";
$connection = new MongoClient();
$collection = $connection->$colName->$database;
$cursor = $collection->find();
foreach($cursor as $cur)
echo '"'.$cur['field_1'].'","'.$cur['field_2']."\"\n";
This code will dump your selected database to the a json file
$mongoExport = 'c:\mongodb\mongoexport'; //full path to mongoexport binary
$database = 'test';
$collection = 'foo';
$file = "c:\\temp\\foo.json"
exec(sprintf("%s -d %s -c %s -o %s",
$mongoExport,
$database,
$collection,
$file
));
And this is using pure PHP, for sure will be more fast the mongoexport option, with large collections:
$database = 'test';
$collection = 'foo';
$m = new MongoClient();
$col = $m->selectDB($database)->$collection;
$json = json_encode(iterator_to_array($col->find()));
set_time_limit(0);
ob_start();
error_reporting(E_ALL);
ini_set("display_errors",1);
$conn = new MongoClient("mongodb://Hostname:27017", array("replicaSet" => "rs0"));
if(!$conn){
die("Unable to connect with mongodb");
}
$db = $conn-><DB NAME>; // DB name
$col1 = $db-><colname>;
$col2 = $db-><colname>; // collection name which u want .
$filterCountry = array("status"=>"1"); // where query
$records = $col1->find($filterCountry);
$fp= fopen('exampleTest11.csv', 'w'); // open csv file in which u want write data.
$headings[] = "Code";
$headings[] = "Status" ;
$headings[] = "EMP CODE";
fputcsv($fp, $headings); // PUT Headings .
$cnt =0;
foreach($records as $val) {
$csvarr = array();
$csvarr['code']= $val['code']; // fetch data from database.
$csvarr['Status']= $val['status'];
$csvarr['emp_code']= $val['emp_code'];
fputcsv($fp, $csvarr);
$cnt++;
}
echo "Completed Successfully..".$cnt;
For better or worse, I am storing binary information in a database table and am having a problem retrieving it. Each BLOB has a newline prepended to it upon retrieval, at least, I believe it's upon retrieval, as the binary object in the table is exactly the same size as the source file.
I've searched for a similar problem to mine, and the closest I have found is this However, I am using PDO instead of mysql_* and I have checked for empty lines prior to the opening
Here's the retrieval function stored in a separate file that I'm including in my test:
(in raw.php):
function return_raw_rawid($raw_id) {
$data = array();
$aggregate_data = array();
$sql = "SELECT * FROM `raw` WHERE `raw_id` = :rawid";
try {
$db_obj = dbCore::getInstance();
$query = $db_obj->dbh->prepare($sql);
$query->bindValue(':rawid', $raw_id);
if ($query->execute()) {
while($results = $query->fetch(PDO::FETCH_ASSOC)) {
$data['raw_id'] = $results['raw_id'];
$data['filename'] = $results['filename'];
$data['mime_type'] = $results['mime_type'];
$data['file_size'] = $results['file_size'];
$data['file_data'] = $results['file_data'];
$data['test_id'] = $results['test_id'];
$data['user_id'] = $results['user_id'];
$data['time'] = date('Y-m-d H:i:s', $results['time']);
$aggregate_data[] = $data;
} // while
} // if
$query->closeCursor();
return $aggregate_data;
} catch (PDOException $ex) {
$errors[] = $ex;
} // catch
}
Here's the code I'm testing it with in a separate file:
<?php
include 'core/init.php'; // Contains protect_page() and includes for return_raw_rawid
protect_page();
$blob_id = 20;
$blob = return_raw_rawid($blob_id);
$data = ltrim($blob[0]['file_data']);
$name = ltrim($blob[0]['filename']);
$size = ltrim($blob[0]['file_size']);
$type = ltrim($blob[0]['mime_type']);
header("Content-type: $type");
header("Content-length: $size");
header("Content-disposition: attachment; filename=$name");
header("Content-Description: PHP Generated Data");
echo $data;
When I load this page in my browser, it will prompt me to download the file identified by blob_id and has the correct filename and type. However, upon downloading it and opening in ghex, I see that the first byte is '0A' Using cmp original_file downloaded_file I determine that the only difference is this first byte. Googling led me to the ltrim() function that I've (perhaps too) liberally applied above.
I can't tell for sure if this problem is not being caused during upload, though as I said before, I don't believe it is since the "file_size" value in phpmyadmin is exactly the same as the source file. I'm not sure if the use of the aggregate_data array in the retrieval function could be to blame or what.
Any help is greatly appreciated!
Are you sure those 4 header lines are being properly executed? 0x0A is the newline char. You could have a newline in your core/init.php triggering output, and the headers are never executed. With display_errors/error_reporting off, you'd never see the warnings about "headers not sent - output started at line X...".