binary file(pdf) from database on web page using PHP - php

I have uploaded a pdf file (varbinary(MAX)) in MSSQL running on my desktop via VS2010 (Ref) with just the UPDATE statement in the Ref.
The table has additional data associated with the pdf, like name, description, date.
Table in database:
Name | Description | Date | File |
DataSheet | Milling M/C | 2004-01-01 | <Binary data> |
Is it possible to display the table content in a web page as
Name | Description | Date | File |`
DataSheet | Milling M/C | 2004-01-01 | (link to the pdf) |
or
Name | Description | Date | File |
DataSheet | Milling M/C | 2004-01-01 | (an icon of pdf) |
using PHP so that user can click the link/file to view it. There will be lot of rows, I just gave 1 row for example.
Please let me know if I am not clear, thanks in advance.
PS: I did create some images but was not able to post them, sorry about the format
What I have done so far
I am using 'Connect without a DSN (using a connection string)' from here
$conn = new COM ("ADODB.Connection") or die("Cannot start ADO");
$connStr = "PROVIDER=SQLOLEDB;SERVER=".$myServer.";UID=".$myUser.";PWD=".$myPass.";DATABASE=".$myDB;
$conn->open($connStr);
$query = "select * from Table";
$rs = $conn->execute($query);
$num_columns = $rs->Fields->Count();
for ($i=0; $i < $num_columns; $i++) {
$fld[$i] = $rs->Fields($i);
}
while (!$rs->EOF)
{
for ($i=0; $i < $num_columns; $i++) {
echo $fld[$i]->value;
}
$rs->MoveNext();
}
The result I am getting is garbage for binary data.
DataSheet | Milling M/C | 2004-01-01 | some_garbage |

Yes it is possible. Create a link to a separate page that accepts a record is in the query string. For instance, you can link to ViewFile.php?recordid=123.
Then, in ViewFile.php, you can get the binary data, output some headers, and output the binary (I think even echo would suffice for that).
The headers should contain at least a Content-Type header, telling the browser that the binary data is to be interpreted as application/pdf data. If it is not a pdf, you should specify appropriate headers. Lists of valid Content-Types can be found all over the internet.
You can specify a filename too. But the important thing is that you can determine what kind of data it is. If you don't know whether it is an icon or a pdf, you cannot tell the browser either. The browser will need to know (by reading the content-type header) how the data should be interpreted. It cannot guess it, even when the url would have a .pdf extension.

Related

json encoded data is parsed different when GET request is made to localhost and when to remotehost

I wrote a web application and uploaded it to remote server. I used PHP5, MySQL and AngularJS.
differences from local and remote installation are:
----------------------------------------------
| | local host | remote host |
----------------------------------------------
| OS | Fedora 22 | Ubuntu 14.04.2 LTS |
----------------------------------------------
| PHP | 5.6.10 | 5.5.9 |
----------------------------------------------
| Apache | 2.4.12 | 2.4.7 |
----------------------------------------------
| MySQL | 5.6.25 | 5.5.43 |
----------------------------------------------
maybe my problem is connected to version differences or maybe not but in both cases I would like to understand what is causing this difference.
problem description:
when requesting some resource which will return a json encoded list of objects (resulted from a query to MySQL server)
from local server it will be parsed and will look like this
[{id : 1, name: "some name 1"}, {id: 2, "some name 2"}]
but when request is made to remote server, same data will be parsed as:
[{id : "1", name: "some name 1"}, {id: "2", "some name 2"}]
please note that numbers are interpreted as strings and in both cases Content-Type is equal to application/json.
if some other info is needed, I would be glad to provide it.
If you're using PDO prepared statements, it it possible that php have been compiled with different mysql libraries: mysqlng on localhost and libmysqlclient on remote. Check out PHP documentation page about choosing MySQL library to know the difference.
When PHP encodes JSON, it checks only the variable type, not variable content. Thus this code:
$array = array('id' => '1'); // notice '1' has string type
echo json_encode($array);
// {"id": "1"}
produces different output than:
$array = array('id' => 1); // notice '1' has int type
echo json_encode($array);
// {"id": 1}
The point is that libmysqlclient always returns column values as string type, while mysqlng may use PHP's int type for MySQL INT columns. That's why you have array of objects with ID of type int locally and array of objects with ID of type string on remote.
To check out what library does your PHP instance use, see this stackoverflow question.

Getting all projectname values with certain name in a table

So I am creating a website for me and my friends so we can work on projects with each other (Like Google documents), and I am trying to create a thing so we can choose what project we want to work on. Currently I am having trouble getting the names of the projects from the MySQL table.
Here is what I have tried to get the names of the projects
$projects = mysqli_query($link, "SELECT * FROM table WHERE name='". $username ."'");
$projects2 = mysqli_fetch_assoc($projects);
$projects3 = $projects2["projectname"];
And here is an example of the MySQL table
+---------+------------------+------------------+------------------+------------
-+
| name | htmltext | csstext | jstext | projectname
|
+---------+------------------+------------------+------------------+------------
-+
| cow9000 | testing is cool! | testing is cool! | testing is cool! | test
|
| cow9000 | testing is cool! | testing is cool! | testing is cool! | test2
|
+---------+------------------+------------------+------------------+------------
As you can see there are 2 documents that the owner owns, but when I try printing out $project3, it only gives me "test". How would I change my code to get all projectname values?
Sorry if this is confusing, it is hard for me to put it into words. Also, please do point out errors in my code as I only have a couple days of experience in PHP and MySQL (But I am finding that PHP and MySQL is very, very easy for me.)
You already have all of those values. You just access them like you did projectname, by using the name of that column as the key in the $projects2 array:
$projects2 = mysqli_fetch_assoc($projects);
echo $projects2["name"]; // cow9000
echo $projects2["htmltext"]; // testing is cool!
echo $projects2["csstext"]; // testing is cool!
echo $projects2["jstext"]; // testing is cool!
If you want the second row you need to use a loop:
// Prints each row in the order they were retrieved
while($projects2 = mysqli_fetch_assoc($projects)) {
echo $projects2["projectname"]; // test and then test2
}
You have to iterate through the returned data, for example like this:
while ($projects2 = mysqli_fetch_assoc($projects)) {
echo $projects2["projectname"];
}
First it will return test, second test2

How to make alignment on console in php

I am trying to run a script through command prompt in PHP and trying to show the result in tabular form. But due to different character length of words I am not able to show the result properly align.
I want result like this
Book ISBN Department
Operating System 101 CS
C 102 CS
java 103 CS
Can anyone please help me to get this output like this in php on console.
Thanks in advance
If you don't want (or not allowed for some reason) to use libraries, you can use standard php printf / sprintf functions.
The problem with them that if you have values with variable and non-limited width, then you will have to decide if long values will be truncated or break table's layout.
First case:
// fixed width
$mask = "|%5.5s |%-30.30s | x |\n";
printf($mask, 'Num', 'Title');
printf($mask, '1', 'A value that fits the cell');
printf($mask, '2', 'A too long value the end of which will be cut off');
The output is
| Num |Title | x |
| 1 |A value that fits the cell | x |
| 2 |A too long value the end of wh | x |
Second case:
// only min-width of cells is set
$mask = "|%5s |%-30s | x |\n";
printf($mask, 'Num', 'Title');
printf($mask, '1', 'A value that fits the cell');
printf($mask, '2', 'A too long value that will brake the table');
And here we get
| Num |Title | x |
| 1 |A value that fits the cell | x |
| 2 |A too long value that will brake the table | x |
If neither of that satisfies your needs and you really need a table with flowing width columns, than you have to calculate maximum width of values in each column. But that is how PEAR::Console_Table exactly works.
You can use PEAR::Console_Table:
Console_Table helps you to display tabular data on a
terminal/shell/console.
Example:
require_once 'Console/Table.php';
$tbl = new Console_Table();
$tbl->setHeaders(array('Language', 'Year'));
$tbl->addRow(array('PHP', 1994));
$tbl->addRow(array('C', 1970));
$tbl->addRow(array('C++', 1983));
echo $tbl->getTable();
Output:
+----------+------+
| Language | Year |
+----------+------+
| PHP | 1994 |
| C | 1970 |
| C++ | 1983 |
+----------+------+
Your best option is to use the Pear Package Console_Table ( http://pear.php.net/package/Console_Table/ ).
To use - on a console you need to install the pear package, running:
pear install Console_Table
this should download the package and install. You can then use a sample script such as:
require_once 'Console/Table.php';
$tbl = new Console_Table();
$tbl->setHeaders(
array('Language', 'Year')
);
$tbl->addRow(array('PHP', 1994));
$tbl->addRow(array('C', 1970));
$tbl->addRow(array('C++', 1983));
echo $tbl->getTable();
You could try the recent simple PHP library ConsoleTable if you don't want to use the standard PHP functions printf/sprintf or the pear package PEAR::Console_Table.
Example:
require_once 'ConsoleTable.php';
$table = new LucidFrame\Console\ConsoleTable();
$table
->addHeader('Language')
->addHeader('Year')
->addRow()
->addColumn('PHP')
->addColumn(1994)
->addRow()
->addColumn('C++')
->addColumn(1983)
->addRow()
->addColumn('C')
->addColumn(1970)
->display()
;
Output:
+----------+------+
| Language | Year |
+----------+------+
| PHP | 1994 |
| C++ | 1983 |
| C | 1970 |
+----------+------+
See more example usages at its github page.
Too old, but i went trough the same now and used str_pad, just set the lenght as the size of your column and thats it
regards.
The CLIFramework table generator helps you get the job done very easily and it supports text alignment, text color, background color, text wrapping, text overflow handling.. etc
Here is the tutorial: https://github.com/c9s/CLIFramework/wiki/Using-Table-Component
Sample code: https://github.com/c9s/CLIFramework/blob/master/example/table.php
use CLIFramework\Component\Table\Table;
$table = new Table;
$table->setHeaders([ 'Published Date', 'Title', 'Description' ]);
$table->addRow(array(
"September 16, 2014",
"Title",
"Description",
29.5
));
$table->addRow(array(
"November 4, 2014",
"Hooked: How to Build Habit-Forming Products",
["Why do some products capture widespread attention whil..."],
99,
));
echo $table->render();
Just in case someone wants to do that in PHP I posted a gist on Github
https://gist.github.com/redestructa/2a7691e7f3ae69ec5161220c99e2d1b3
simply call:
$output = $tablePrinter->printLinesIntoArray($items, ['title', 'chilProp2']);
you may need to adapt the code if you are using a php version older than 7.2
after that call echo or writeLine depending on your environment.

PHP TZ setting length

I was wonder what is the maximum length of the timezone settings in PHP? I'm storing the string in a database, and would like to keep the length as short as possible, but i see timezones like "Canada/East-Saskatchewan", which goes beyond our current limit.
If I could just get a list of all the supported timezone string, I can sort them, but they are currently split on to several different pages.
linky: http://www.php.net/manual/en/timezones.php
Edit June 2021 Answer is 64. Why? That's the width of the column used in MySQL to store those timezone name strings.
The zoneinfo database behind those time zone strings just added new prefixes. To America/Argentina/ComodRivadavia, formerly the longest timezone string, they added posix/America/Argentina/ComodRivadavia and right/America/Argentina/ComodRivadavia, both with a length of 38. This is up from 32, the previous longest string.
And here is the complete PHP code to find that:
<?php
$timezone_identifiers = DateTimeZone::listIdentifiers();
$maxlen = 0;
foreach($timezone_identifiers as $id)
{
if(strlen($id) > $maxlen)
$maxlen = strlen($id);
}
echo "Max Length: $maxlen";
/*
Output:
Max Length: 32
*/
?>
The Olson database — available from ftp://ftp.iana.org/tz/releases/ or http://www.iana.org/time-zones (but see also http://www.twinsun.com/tz/tz-link.htm* and http://en.wikipedia.org/wiki/Tz_database) — is the source of these names. The documentation in the file Theory includes a description of how the zone names are formed. This would help you establish how long names can be.
The longest 'current' names are 30 characters (America/Argentina/Buenos_Aires,
America/Argentina/Rio_Gallegos, America/North_Dakota/New_Salem); the longest 'backwards compatibility' name is 32 characters (America/Argentina/ComodRivadavia).
* Note that the TwinSun site has not been updated for some time and has some outdated links (such as suggesting that the Olson database is available from ftp://ftp.elsie.nci.nih.gov — it is now available from IANA instead).
From the manual:
<?php
$timezone_identifiers = DateTimeZone::listIdentifiers();
for ($i=0; $i < 5; $i++) {
echo "$timezone_identifiers[$i]\n";
}
?>
If you are using MySQL with PHP, consider that MySQL already stores Olson timezone names in the "mysql" system database, in a table called "time_zone_name", in a column called "name". One option is to choose the length of your column to match the length that MySQL uses. In MySQL 5.7, the timezone name length is 64 characters. To determine the length in use on your MySQL installation, follow the example below:
mysql> use mysql
Database changed
mysql> describe time_zone_name;
+--------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| Name | char(64) | NO | PRI | NULL | |
| Time_zone_id | int(10) unsigned | NO | | NULL | |
+--------------+------------------+------+-----+---------+-------+
2 rows in set (0.01 sec)

MySQL or PHP is appending a  whenever the £ is used

Answers provided have all been great, I mentioned in the comments of Alnitak's answer that I would need to go take a look at my CSV Generation script because for whatever reason it wasn't outputting UTF-8.
As was correctly pointed out, it WAS outputting UTF-8 - the problem existed with Ye Olde Microsoft Excel which wasn't picking up the encoding the way I would have liked.
My existing CSV generation looked something like:
// Create file and exit;
$filename = $file."_".date("Y-m-d_H-i",time());
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: csv" . date("Y-m-d") . ".csv");
header( "Content-disposition: filename=".$filename.".csv");
echo $csv_output;
It now looks like:
// Create file and exit;
$filename = $file."_".date("Y-m-d_H-i",time());
header("Content-type: text/csv; charset=ISO-8859-1");
header("Content-disposition: csv" . date("Y-m-d") . ".csv");
header("Content-disposition: filename=".$filename.".csv");
echo iconv('UTF-8', 'ISO-8859-1', $csv_output);
-------------------------------------------------------
ORIGINAL QUESTION
Hi,
I've got a form which collects data, form works ok but I've just noticed that if someone types or uses a '£' symbol, the MySQL DB ends up with '£'.
Not really sure where or how to stop this from happening, code and DB information to follow:
MySQL details
mysql> SHOW COLUMNS FROM fraud_report;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | mediumint(9) | | PRI | NULL | auto_increment |
| crm_number | varchar(32) | YES | | NULL | |
| datacash_ref | varchar(32) | YES | | NULL | |
| amount | varchar(32) | YES | | NULL | |
| sales_date | varchar(32) | YES | | NULL | |
| domain | varchar(32) | YES | | NULL | |
| date_added | datetime | YES | | NULL | |
| agent_added | varchar(32) | YES | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
8 rows in set (0.03 sec)
PHP Function
function processFraudForm($crm_number, $datacash_ref, $amount, $sales_date, $domain, $agent_added) {
// Insert Data to DB
$sql = "INSERT INTO fraud_report (id, crm_number, datacash_ref, amount, sales_date, domain, date_added, agent_added) VALUES (NULL, '$crm_number', '$datacash_ref', '$amount', '$sales_date', '$domain', NOW(), '$agent_added')";
$result = mysql_query($sql) or die (mysql_error());
if ($result) {
$outcome = "<div id=\"success\">Emails sent and database updated.</div>";
} else {
$outcome = "<div id=\"error\">Something went wrong!</div>";
}
return $outcome;
}
Example DB Entry
+----+------------+--------------+---------+------------+--------------------+---------------------+------------------+
| id | crm_number | datacash_ref | amount | sales_date | domain | date_added | agent_added |
+----+------------+--------------+---------+------------+--------------------+---------------------+------------------+
| 13 | 100xxxxxxx | 10000000 | £10.93 | 18/12/08 | blargh.com | 2008-12-22 10:53:53 | agent.name |
What you're seeing is UTF-8 encoding - it's a way of storing Unicode characters in a relatively compact format.
The pound symbol has value 0x00a3 in Unicode, but when it's written in UTF-8 that becomes 0xc2 0xa3 and that's what's stored in the database. It seems that your database table is already set to use UTF-8 encoding. This is a good thing!
If you pull the value back out from the database and display it on a UTF-8 compatible terminal (or on a web page that's declared as being UTF-8 encoded) it will look like a normal pound sign again.
£ is 0xC2 0xA3 which is the UTF-8 encoding for £ symbol - so you're storing it as UTF-8, but presumably viewing it as Latin-1 or something other than UTF-8
It's useful to know how to spot and decode UTF-8 by hand - check the wikipedia page for info on how the encoding works:
0xC2A3 = 110 00010 10 100011
The bold parts are the actual
"payload", which gives 10100011,
which is 0xA3, the pound symbol.
In PHP, another small scale solution is to do a string conversion on the returned utf8 string:
print iconv('UTF-8', 'ASCII//TRANSLIT', "Mystring â"); //"Mystring "
Or in other platforms fire a system call to the inconv command (linux / osx)
http://php.net/manual/en/function.iconv.php#83238
You need to serve your HTML in utf-8 encoding (actually everyone needs to do this I think!)
Header like:
Content-Type: text/html; charset=UTF-8
Or the equivalent. Double check the details though. Should always be declaring the charset as a browser can default to anything it likes.
To remove a  use:
$column = str_replace("\xc2\xa0", '', $column);
Credits among others: How to remove all occurrences of c2a0 in a string with PHP?
Thanks a lot. I had been suspecting mysql for being currupting the pound symbol. Now all i need to do is wherever the csv record is generated, just use wrap them incov funciton. Though this is a good job, I am happy, at least someone showed exactly what to do. I sincerly appreciate dislaying the previous and the new 'header' values. It was a great help to me.
-mark
If you save line "The £50,000 Development Challenge" in two different data type column i.e. "varchar" & "text" field.
Before i save i have replaced the symbol with html equi value using following function.
str_replace("£", "£", $title);
You will find that value stored in text fields is &pound where as in varchar its "£".

Categories