php + mysql 取得数据库中二进制文件,生成链接供打开

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php + mysql 取得数据库中二进制文件,生成链接供打开相关的知识,希望对你有一定的参考价值。

最近做个WB项目,有个上传文件功能,可以上传txt、jpg、png、doc等等类型文件。我把上传功能做完了,文件以二进制形式存在库表longblob 类型字段中。现在想已链接的形式把它显示出来供打开查看。个人认为应该先把二进制的字节流取出然后生成文件保存到本地磁盘上然后给个超链接。没有弄过php很蛋疼,不知道如果实现。麻烦各位高手赐教!最好提供代码!!!!!

参考技术A filelist.php
<?php
................
$result=mysql_db_query(.........id,filename.........);#查询结果并存入变量中
$rows=mysql_num_rows($result);#得出数据行数
for($i=0;$i<$rows;$i++)
$total=mysql_fetch_array($result);
echo
"<li><a
href='filedown.php?fileid=$total[id]&filename=$total[filename]'
target
='_blank'
>$total[filename]</a></li>";

...............
?>
filedown.php
<?php
$fid=$_GET['fileid'];
$fname=$_GET['filename'];
.....................
.....................
$result=mysql_db_query(.........,"select
id,filename,datasize,filedata
from
ftable
where
id='$fid'",.........);
$total=mysql_fetch_array($result);
$file_size=$total[datasize];
header("Content-type:application/octet-stream");
header("Accept-Ranges:bytes");
header("Accept-Length:$file_size");
header("Content-Disposition:attachment;filename=".$total[filename]);
echo
$total[filedata];
...............
?>
======
你说把二进制的字节流取出生成文件保存到磁盘然后给个超链接,
这样做法没意义,你既然把它存在库里了那直接stream给用户是最好的方式,否则你还得考虑把它还原到文件夹用户使用完后怎么处理的问题?如果保留那当初就应该同时把它存在文件夹省得者多麻烦,如果不保留那反复生成删除还有共享问题反而加重服务器负担。要么一次生成定期择优删除,又有许多代码有的写了。。。

如何在sql中产生随机的十六进制颜色?

【中文标题】如何在sql中产生随机的十六进制颜色?【英文标题】:How to produce random hex color in sql? 【发布时间】:2014-04-12 12:29:55 【问题描述】:

这对我来说是一个相当难的话题,因为 SQL 不是我最好的技能;)

我必须在数据库行中插入随机的十六进制颜色。我该怎么做?是否可以创建会绘制数字的函数?

【问题讨论】:

哪个数据库? (MySQL, oracle, postgresql, ...) 是的,哪个数据库? 我以为是 MySQL,因为他在第一个答案发布几天后回复了一些关于 MySQL 的内容。 【参考方案1】:

猜你需要使用 rand - https://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_rand - 即

INSERT INTO ... VALUES ( ... , ROUND(RAND(255 * 255 * 255)), ...)

【讨论】:

两个问题:我需要十六进制格式 - 如何排列字母?如何将其更改为函数返回 6 个长度的数字而不是 rand 每个数字? 你可以直接查找字符串函数HEX 进行转换吗?【参考方案2】:
with cte1 as (
select round(round(rand(),1)*15,0) as hex1,
 round(round(rand(),1)*15,0) as hex2,
 round(round(rand(),1)*15,0) as hex3,
 round(round(rand(),1)*15,0) as hex4,
 round(round(rand(),1)*15,0) as hex5,
 round(round(rand(),1)*15,0) as hex6
),
cte2 as (
select case when hex1 = 10 then 'A' 
when hex1 = 11 then 'B'
when hex1 = 12 then 'C'
when hex1 = 13 then 'D'
when hex1 = 14 then 'E'
when hex1 = 15 then 'F'
else str(hex1) end as hex1h,
case when hex2 = 10 then 'A' 
when hex2 = 11 then 'B'
when hex2 = 12 then 'C'
when hex2 = 13 then 'D'
when hex2 = 14 then 'E'
when hex2 = 15 then 'F'
else str(hex2) end as hex2h,
case when hex3 = 10 then 'A' 
when hex3 = 11 then 'B'
when hex3 = 12 then 'C'
when hex3 = 13 then 'D'
when hex3 = 14 then 'E'
when hex3 = 15 then 'F'
else str(hex3) end as hex3h,
case when hex4 = 10 then 'A' 
when hex4 = 11 then 'B'
when hex4 = 12 then 'C'
when hex4 = 13 then 'D'
when hex4 = 14 then 'E'
when hex4 = 15 then 'F'
else str(hex4) end as hex4h,
case when hex5 = 10 then 'A' 
when hex5 = 11 then 'B'
when hex5 = 12 then 'C'
when hex5 = 13 then 'D'
when hex5 = 14 then 'E'
when hex5 = 15 then 'F'
else str(hex5) end as hex5h,
case when hex6 = 10 then 'A' 
when hex6 = 11 then 'B'
when hex6 = 12 then 'C'
when hex6 = 13 then 'D'
when hex6 = 14 then 'E'
when hex6 = 15 then 'F'
else str(hex6) end as hex6h from cte1)

select '#'+ltrim(hex1h)+ltrim(hex2h)+ltrim(hex3h)+ltrim(hex4h)+ltrim(hex5h)+ltrim(hex6h) from cte2

【讨论】:

【参考方案3】:

这是下面解释的逻辑,包装在 MySQL 的函数中。它非常易于使用。

mysql> select random_color();
+----------------+
| random_color() |
+----------------+
| #8F50B4        |
+----------------+
1 row in set (0.00 sec)

它可以被一遍又一遍地调用,每次都会有不同的颜色。

CREATE FUNCTION `random_color`() RETURNS char(7) CHARSET latin1 DETERMINISTIC
BEGIN
 DECLARE str CHAR(7);
 SET str = concat('#',SUBSTRING((lpad(hex(round(rand() * 10000000)),6,0)),-6));
 RETURN str;
END;

这将在 MySQL 中为您提供六位十六进制数字代码

SELECT concat('#',SUBSTRING((lpad(hex(round(rand() * 10000000)),6,0)),-6))

这是一个很棒的,可以给你增加颜色

SELECT *, 
       concat('#',SUBSTRING((lpad(hex(@curRow := @curRow + 10),6,0)),-6)) AS color 
FROM table 
       INNER JOIN (SELECT @curRow := 5426175) color_start_point

【讨论】:

【参考方案4】:
SET [Color] =  '#' +  CONVERT(VARCHAR(max), CRYPT_GEN_RANDOM(3), 2)

【讨论】:

【参考方案5】:

这是一个 SQL Server 函数,可在 2012 年以后的所有版本中使用,生成十六进制格式的随机 HTML 颜色代码,即#AABB00。它也需要一个视图,下面也提供了它。

该功能为您提供了避免使用浅色或深色的选项,如果您尝试生成不会发生太大冲突的背景色和前景色(即深色背景上的深色文本),这将非常有用。

CREATE FUNCTION dbo.Get_Random_Colour (@intStyle tinyint = 0)  
RETURNS varchar(7)

/*
* Purpose:      Returns the HTML colour code for a random colour
* Inputs:       @intStyle - 0: does not filter the colour range
*                           1: avoid dark colours
*                           2: avoid light colours
*/

AS  
BEGIN 

DECLARE @c1 char(2), @c2 char(2), @c3 char(2)
DECLARE @i1 tinyint, @i2 tinyint, @i3 tinyint
DECLARE @strResult As varchar(255)
DECLARE @intLow tinyint = 0
DECLARE @intHigh tinyint = 255

IF @intStyle = 1
    SET @intLow = 80

IF @intStyle = 2
    SET @intHigh = 140


--Generate random numbers
SELECT @i1 = CAST(ROUND((@intHigh-@intLow) * RandNumber + @intLow,0) as int) from dbo.vRandNumber
SELECT @i2 = CAST(ROUND((@intHigh-@intLow) * RandNumber + @intLow,0) as int) from dbo.vRandNumber
SELECT @i3 = CAST(ROUND((@intHigh-@intLow) * RandNumber + @intLow,0) as int) from dbo.vRandNumber

--Convert them to hex format
SELECT @c1 = FORMAT(@i1, 'X')
SELECT @c2 = FORMAT(@i2, 'X')
SELECT @c3 = FORMAT(@i3, 'X')

--Pad them to two characters
SELECT @strResult = '#' 
    + REPLICATE('0', 2-LEN(@c1)) + @c1
    + REPLICATE('0', 2-LEN(@c2)) + @c2
    + REPLICATE('0', 2-LEN(@c3)) + @c3



RETURN @strResult

END
GO

这是函数所依赖的视图:

CREATE VIEW [dbo].[vRandNumber]
AS
SELECT RAND() as RandNumber

【讨论】:

【参考方案6】:

我不确定您使用的是哪个 DBMS,但是此解决方案适用于 SQL Server,如果您知道相应的语法和功能,则可以将其应用于不同的 DBMS。

(我会尽量简短)

十六进制颜色基本上是一个十六进制的VARBINARY 值,几乎所有 DBMS 都支持。您只需要正确的转换即可将其与您的需求绑定。

例如,如果我们将字符串foo 转换为VARBINARY,它将返回0x666F6F 的值,如果我们转换回VARCHAR,它将返回foo

SELECT CAST('foo' AS VARBINARY) 
-- Returns : 0x666F6F

SELECT CAST(0x666F6F AS VARCHAR)
-- Returns : foo

因此,即使输出不同,它的值也与对应的数据类型相同。这也适用于颜色(十六进制到 rgb,rgb 到十六进制,十六进制到二进制等等)。

现在,您知道十六进制颜色使用 VARBINARY 数据类型,这将是我们在此解决方案中的目标。

首先是使用 RGB 值(这是 INT 值的另一种数据类型)生成 VARBINARY。 RGB 值是三个不同的值,分别代表红色、绿色和蓝色。它们每个的最小数量为 0,最大为 255。因此,如果我们执行 RGB(0,0,0),这将返回 #000000(黑色),RGB(255,255,255) 返回 #FFFFFF(白色)。

哦,我忘了,在这个转换中你不需要任何特殊的方程,因为 DBMS 已经在处理这个了。

因此,您的第一个目标是执行一个函数,该函数采用 RGB 值(最小值为 0,最大值为 255),然后将其转换为十六进制 VARBINARY,这将为您提供十六进制颜色。

要从 RGB 转换为十六进制,您需要知道每 2 个十六进制表示一个 RGB 值。比如#BA55D3对应rgb(186,85,211) 它的实际十六进制是

R = 0xBA G = 0x55 B = 0xD3

在哪里

0xBA = 186 0x55 = 18 0xD3 = 211

。因此,从每种十六进制颜色中,您需要将其分成 3 组,每组两个值来表示 RGB 值。

如果您将 0xBA 转换为 INT,它将为您提供 186,这是红色部分的值。

 SELECT 
    CAST(0xBA AS INT) 
    -- Returns : 186 

同样的事情也适用于其余部分。

现在,我们需要我们的函数来为我们完成这项工作,为此,我创建了一个函数,它只需要三个 int 值并将它们转换为 VARBINARY 这有助于我将其转换回 varchar 以格式化输出为十六进制颜色值。

CREATE FUNCTION RGBToHex
(
        @R          INT,
        @G          INT,
        @B          INT
)
RETURNS VARCHAR(7)
AS
BEGIN
DECLARE 
        @VarR       VARBINARY,
        @VarG       VARBINARY,
        @VarB       VARBINARY,

        @Result     VARCHAR(7)

SELECT 
     @VarR  = CONVERT(VARBINARY, @R) * 1 , 
     @VarG  = CONVERT(VARBINARY, @G) * 1 , 
     @VarB  = CONVERT(VARBINARY, @B) * 1

SET @Result = '#' + SUBSTRING(Convert(VARCHAR(MAX),@VarR, 1), 3, 2) + SUBSTRING(Convert(VARCHAR(MAX),@VarG, 1), 3, 2) + SUBSTRING(Convert(VARCHAR(MAX),@VarB, 1), 3, 2)


    RETURN @Result

END

例子:

SELECT 
    RGBToHex(186,85,211)
-- Returns : #BA55D3

现在,该函数已经可以使用了,我们只需要一种在该函数中随机化三个 INT 的方法,每次都得到一个随机颜色,记住 RGB 的最小和最大 (0-255) 值.

在 SQL Server 中,为了简单起见,我使用了递归查询,您可以使用自己的方法或函数进行自己的查询。

;WITH CTE AS (
    SELECT 
        ABS(CHECKSUM(NewId())) % 256 AS R , 
        ABS(CHECKSUM(NewId())) % 256 AS G ,
        ABS(CHECKSUM(NewId())) % 256 AS B
)   
SELECT 
    dbo.RGBToHex(R,G,B)
FROM CTE 

在上面的查询中,我为每一列设置了 0-255 之间的随机数,然后我只是将这些值放入函数中以生成新颜色。

如果你需要一个反转函数来获取颜色的十六进制并返回 RGB 值,你可以使用这个函数:

CREATE FUNCTION HexToRGB
(
        @Hex        VARCHAR(7)   
)
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE 

        @VarH       VARCHAR(6), 
        @R          INT, 
        @G          INT, 
        @B          INT,
        @Result     VARCHAR(100)

SET @VarH = (CASE WHEN LEFT(@Hex, 1) = '#' THEN SUBSTRING(@Hex, 2,6) ELSE @Hex END)

SELECT
    @R  =   CONVERT(INT, CONVERT(VARBINARY, '0x' +  SUBSTRING(@VarH, 1,2), 1) ),
    @G  =   CONVERT(INT, CONVERT(VARBINARY, '0x' +  SUBSTRING(@VarH, 3,2), 1) ),
    @B  =   CONVERT(INT, CONVERT(VARBINARY, '0x' +  SUBSTRING(@VarH, 5,2), 1) )

SET @Result = 'rgb('    + CAST(@R AS VARCHAR(3) ) + ',' + CAST(@G AS VARCHAR(3) )   +  ','  +   CAST(@B AS VARCHAR(3) )     + ')' 

    RETURN @Result

END

【讨论】:

【参考方案7】:

如果您使用的是 MySQL

select concat("#", conv(round(rand() * 255), 10, 16), conv(round(rand() * 255), 10, 16), conv(round(rand() * 255), 10, 16));

【讨论】:

并不总是产生带有 # 后面 6 个字符的输出。【参考方案8】:

这是 PostgreSQL 的解决方案。

SELECT concat('#',lpad(to_hex(round(random() * 10000000)::int4),6,'0'))

我使用该代码将随机颜色设置为表格的Color 字段:

UPDATE "MyTable" SET "Color" = concat('#',lpad(to_hex(round(random() * 10000000)::int8),6,'0'));

【讨论】:

【参考方案9】:

对于所有 SQL 查询(MySql、SQL Server 等),此方法都可以使用

在 sql 中,我们可以使用 substring 函数生成随机颜色。请记住,在 sql 中,字符索引从 1 开始(not 0 like javascript)

select concat('#',substring('0123456789ABCDEF',round(rand() * 15)+1,1),substring('0123456789ABCDEF',round(rand() * 15)+1,1),substring('0123456789ABCDEF',round(rand() * 15)+1,1),substring('0123456789ABCDEF',round(rand() * 15)+1,1),substring('0123456789ABCDEF',round(rand() * 15)+1,1),substring('0123456789ABCDEF',round(rand() * 15)+1,1));

round(rand() * 15) 给出一个介于 0 和 15 之间的随机数,包括 0 和 15。这就是为什么我们将 1 添加到它以获得 1 作为子字符串索引的最小值

只获得浅色:-

select concat('#',substring('0123456789ABCDEF',round(rand() * 8)+8,1),substring('0123456789ABCDEF',round(rand() * 15)+1,1),substring('0123456789ABCDEF',round(rand() * 8)+8,1),substring('0123456789ABCDEF',round(rand() * 15)+1,1),substring('0123456789ABCDEF',round(rand() * 8)+8,1),substring('0123456789ABCDEF',round(rand() * 15)+1,1));

只获得深色:-

select concat('#',substring('0123456789ABCDEF',round(rand() * 7)+1,1),substring('0123456789ABCDEF',round(rand() * 15)+1,1),substring('0123456789ABCDEF',round(rand() * 7)+1,1),substring('0123456789ABCDEF',round(rand() * 15)+1,1),substring('0123456789ABCDEF',round(rand() * 7)+1,1),substring('0123456789ABCDEF',round(rand() * 15)+1,1));

更新:-

在上述所有情况下,我们可以使用一个临时变量来获得重复范围值,以最小化查询,如

set @r='0123456789ABCDEF';
select concat('#',substring(@r,round(rand() * 15)+1,1),substring(@r,round(rand() * 15)+1,1),substring(@r,round(rand() * 15)+1,1),substring(@r,round(rand() * 15)+1,1),substring(@r,round(rand() * 15)+1,1),substring(@r,round(rand() * 15)+1,1));

【讨论】:

【参考方案10】:

这在 MySQL 中对我有用:

mysql> SELECT CONCAT('#',LPAD(CONV(ROUND(RAND()*16777215),10,16),6,0)) AS color;
+---------+
| color   |
+---------+
| #0E74A9 |
+---------+
1 row in set (0.00 sec)

简短说明:

16777215是最大24位无符号整数,即:224-1 乘以RAND()ROUND()'ed 得到RGB 颜色范围内的随机无符号整数:(0, 224-1) 然后,将基数 ​​10 转换为基数 16 得到十六进制数 LPAD() 向左补零 最后,CONCAT() 得到 '#' 字符

【讨论】:

以上是关于php + mysql 取得数据库中二进制文件,生成链接供打开的主要内容,如果未能解决你的问题,请参考以下文章

php文件以二进制形式上传并放入到数据库中

使用php百度BAE怎么连接数据库啊

如何在sql中产生随机的十六进制颜色?

PHP怎么取得MYSQL字段(值)的总和!

mysql-删除日志文件命令详解

PHP如何取得mysql字段值并记算时间?