问题标签 [php-stream-wrappers]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
168 浏览

php - 如何确定字符串是否指向 PHP 中的有效文件或包装器?

假设我想知道传递给 fopen 的字符串是否代表文件路径或有效的包装器(例如 "/home/user/example.txt"vs "php://input")。这是为了从内容中创建一个 tmpfilephp://input以解决fseekPHP包装器的限制。

如下所示,file_exists适用于文件,但不适用于包装器 URI:

唯一返回 true 的是文件。我找到了 stream_get_wrappers() 但我想避免使检查过于复杂(例如使用字符串比较来尝试检测包装器)。

使用 stream_get_meta_data 似乎也有效,但它需要先调用 fopen,这会阻塞错误日志。

生产

我可以使用wrapper_type由返回的数组中的stream_get_meta_data,但如果文件或包装器 URI 不存在,它仍会将垃圾放入日志中,我想避免这种情况。

检测我的输入字符串(要传递给 fopen)是否包含现有文件的有效文件路径有效的 PHP 包装器,或者两者都不包含的最佳方法是什么?

更新:我找到了解决问题的解决方法,但代价是额外fopen调用。我把这个放在下面的答案中。

0 投票
1 回答
1730 浏览

php - 将 zip:// 包装器用于包含名称未知的单个文件的存档

zip:// PHP 允许使用wrapper即时读取 ZIP 文件:

一切都好,当您知道压缩文件名时。这不是我的情况:我的应用程序必须处理包含单个文件的 ZIP 存档,在打开存档之前该文件的名称未知。

是否有一个选项告诉包装器打开存档中的第一个文件,没有文件名?

我知道我可以使用ZipArchive 或 Zip Functions,我只想保持简单并尽可能使用流包装器。

0 投票
2 回答
1896 浏览

php - 如果没有数据传输,PHP 流超时

我目前正在实现一个获取图像文件并在本地缓存它们的 PHP 类。这些图像可能来自其他本地来源,通过 HTTP 或使用 Guzzle 客户端的 HTTP。使用 PHP 流包装器,我应该能够以相同的方式处理所有源。

如果没有数据通过流传输,我现在要做的是实现超时。这应该处理以下情况:

  1. 首先无法建立流。这可能应该在fopen通话时处理,而不是超时。
  2. 流已建立,但没有数据传输。
  3. 流已建立,数据已传输,但在传输过程中会停止一段时间。

我想我可以做到这一切,stream_set_timeout但我不太清楚这实际上是做什么的。如果流上的任何操作花费的时间超过允许的时间,超时是否适用,即我可以执行两次需要 0.5 秒且超时为 0.75 秒的事情?还是仅当没有数据通过流传输的时间超过允许的时间时才适用?

我试图用这个简短的脚本测试行为:

虽然响应reqres.in延迟了 5 秒,但我总是得到false1 秒的超时。请问有人可以解释一下吗?

0 投票
3 回答
11999 浏览

php - 从资源创建流

我知道我可以使用fopen函数从文件名(真实文件名或 URL)创建PHP 流:

生成的流 ( $stream) 是从 URL 创建的“流”类型的资源php://temp

但是我怎样才能从资源中创建一个像上面这样的流呢?


我为什么要问这个?

我正在开发一个PSR-7库,并且我用一个类实现了 PSR-7 StreamInterface 。Stream为了创建Stream实例,我决定也实现一个StreamFactory。它的接口 ,StreamFactoryInterface是在PSR-17(HTTP 工厂)提案中定义的。

StreamFactoryInterface定义了一个名为 的方法,该方法createStreamFromResource- 符合其官方评论 - 应该:

从现有资源创建新流。

流必须是可读的并且可能是可写的。

所以工厂方法接收一个资源作为参数。并且,在其具体实现中,Stream创建了一个新对象——它也接收一个资源作为参数。

这是问题所在:

为简单起见,假设Stream该类仅适用于流,例如“流”类型的资源。如果它接收到的资源不是"stream"类型的,它会拒绝它。

那么,如果资源参数createStreamFromResource还不是“流”类型的资源呢?如何将其转换为流,例如转换为"stream"类型的资源,以便我可以进一步将其传递给Stream使用它创建新对象的调用?有没有办法(PHP 方法、函数或强制转换函数)来完成这项任务?

笔记:

  • 为清楚起见,我准备了一个完整的示例testStream.phpStream
  • 我还发布了工厂接口的具体实现:StreamFactory带有方法的类createStreamFromResource。调用此方法应该是我在testStream.php.
  • 此外,我还介绍了类StreamResponse,以便您可以根据需要直接测试所有内容。这两个类是我真实代码的一个非常简化的版本。
  • 在我的代码中,我用"@asking"标记了两个提问的地方。

非常感谢您的时间和耐心!


testStream.php(测试页面)

StreamFactory 类(因为我有它,所以没有简化)

Stream 类(非常简化)

Response 类(非常简化)

0 投票
0 回答
329 浏览

php - CURLOPT_USERPWD 等效于 stream_context_create

USERPWD使用stream_context_create时可以设置吗?

我试过这样

我只是想知道它是正确的等价物吗?并且需要 base64_encode 吗?

0 投票
0 回答
609 浏览

php - 如何为自定义 PHP 流包装器设置默认块大小

当使用 PHP 的流包装器时,可以在客户端设置块大小stream_set_chunk_size

但是,无论如何要从自定义流包装器实现本身指定块大小?

例如,一个实现stream_write接收字节集,但字节长度默认为 8192 字节。我想知道是否可以更改该默认字节长度。

0 投票
1 回答
362 浏览

php - 如何实现 PHP 流包装器来修改另一个包装器的输出?

我使用 PHPzip://流包装器逐行解析大型 XML 文件。例如:

XML 文件通常会包含XMLReader不喜欢的狡猾的 UTF 控制字符。所以我想实现一个自定义流包装器,我可以将zip://流的输出传递给它,它将preg_replace在每一行运行一个来删除这些字符。

我的梦想是能够做到这一点:

XMLReader愉快地阅读了整理好的节点。我已经找到了一种基于传递给我的包装器的路径来重建 zip 流 URI 的方法:

但是我对打开zip://流的最佳方式感到困惑,这样我就可以修改它的输出并将结果传递给XMLReader. 谁能给我有关如何实现它的任何指示?

0 投票
1 回答
113 浏览

java - PHP; 从外部网址获取帖子字符串(JAVA)

我需要将字符串数据发送到作为客户端 API 的外部 url,但我总是让服务器发回一个错误,然后我检查了用 JAVA 编写的服务器中的日志,它抛出了一个异常

"java.lang.NumberFormatException: 对于输入字符串:"{"success":false,"errorCode":"500","message":"Unknown Error!","value":null,"totalPageCount":0,"页脚值“:空}”

这是我的一段 php 代码:

我很确定我发送到服务器的数据格式正确,因为我可以访问日志,而且我知道来自服务器的所有响应参数都是 JSON、UTF-8 和 post 方法,有什么我错过了吗?

如果需要更多信息,请告诉我,谢谢。

0 投票
8 回答
505 浏览

php - 从 URL 复制的文件被截断

我在复制文件时遇到问题。我的代码:

copy()给真,文件已创建,但文件末尾的某些行丢失...文件为 3.6MB,文件末尾的 0.3 丢失...

如果我手动下载文件一切都很好,所以源是完整的......

如果我获取文件内容file_get_contents()并尝试使用文件写入功能将其保存在文件中,我实际上会遇到同样的问题......

我不认为upload_max_filesize并且post_max_size实际上参与其中,copy()但它们设置为 20MB

任何提示?

谢谢

0 投票
0 回答
93 浏览

php - curl 有效,大多数域和 IP 的套接字都失败

我的本地 mac 主机无法以任何形式使用 PHP 的文件流包装器来处理 HTTP 请求(这是使用 composer 等所必需的)。

如果我使用 curl 驱动程序请求完全相同的资源,一切都很好。这是我直接从 PHP 文档中复制的两个程序:

这个是卷曲的,它每次都可以正常工作。

这个使用 fopen,并且在php.ini. 此失败与 file_get_contents 或任何其他基于文件流的方法相同。

这导致:

我试过 PHP 7.1 和 PHP 7.3。

这是我的 ini 文件的示例,其中设置减少:

对于流在php --info

一些事实:

  1. 我用brew.
  2. 所有 URL 都存在此问题
  3. 我们知道它不是防火墙(curl 有效)
  4. allow_url_fopenOn
  5. 仅在打开流时发生
  6. 多次安装 PHP 有这个问题。
  7. 即使使用 fstreamopen 连接$fp = fsockopen("1.1.1.1", 80, $errno, $errstr, 30);也有相同的延迟。
  8. 如果去掉域名直接使用1.1.1.1之类的IP,问题就没有了。但是,当我请求php -r "copy('http://54.36.53.46', 'composer-setup.php');"相同的超时失败时返回。