Skip to content

Commit 93bb6f5

Browse files
committed
add filePathCompatible option for php5.x
1 parent 16b47c6 commit 93bb6f5

File tree

2 files changed

+168
-5
lines changed

2 files changed

+168
-5
lines changed

src/OSS/OssClient.php

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,21 @@ private function __initNewClient($config = array())
206206
}
207207
}
208208

209+
//filePathCompatible
210+
$this->filePathCompatible = false;
211+
if (version_compare(phpversion(), '7.0.0', '<')) {
212+
if (OssUtil::isWin()) {
213+
$this->filePathCompatible = true;
214+
}
215+
}
216+
if (isset($config['filePathCompatible'])) {
217+
if ($config['filePathCompatible'] === true) {
218+
$this->filePathCompatible = true;
219+
} else if ($config['filePathCompatible'] === false) {
220+
$this->filePathCompatible = false;
221+
}
222+
}
223+
209224
self::checkEnv();
210225
}
211226

@@ -1867,7 +1882,7 @@ public function uploadFile($bucket, $object, $file, $options = NULL)
18671882
{
18681883
$this->precheckCommon($bucket, $object, $options);
18691884
OssUtil::throwOssExceptionWithMessageIfEmpty($file, "file path is invalid");
1870-
$file = OssUtil::encodePath($file);
1885+
$file = $this->encodeFilePath($file);
18711886
if (!file_exists($file)) {
18721887
throw new OssException($file . " file does not exist");
18731888
}
@@ -1985,7 +2000,7 @@ public function appendFile($bucket, $object, $file, $position, $options = NULL)
19852000
$this->precheckCommon($bucket, $object, $options);
19862001

19872002
OssUtil::throwOssExceptionWithMessageIfEmpty($file, "file path is invalid");
1988-
$file = OssUtil::encodePath($file);
2003+
$file = $this->encodeFilePath($file);
19892004
if (!file_exists($file)) {
19902005
throw new OssException($file . " file does not exist");
19912006
}
@@ -2651,7 +2666,7 @@ public function multiuploadFile($bucket, $object, $file, $options = null)
26512666
if (empty($file)) {
26522667
throw new OssException("parameter invalid, file is empty");
26532668
}
2654-
$uploadFile = OssUtil::encodePath($file);
2669+
$uploadFile = $this->encodeFilePath($file);
26552670
if (!isset($options[self::OSS_CONTENT_TYPE])) {
26562671
$options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object, $uploadFile);
26572672
}
@@ -2750,7 +2765,7 @@ public function uploadDir($bucket, $prefix, $localDirectory, $exclude = '.|..|.s
27502765
if (!is_string($prefix)) throw new OssException("parameter error, prefix is not string");
27512766
if (empty($localDirectory)) throw new OssException("parameter error, localDirectory is empty");
27522767
$directory = $localDirectory;
2753-
$directory = OssUtil::encodePath($directory);
2768+
$directory = $this->encodeFilePath($directory);
27542769
//If it's not the local directory, throw OSSException.
27552770
if (!is_dir($directory)) {
27562771
throw new OssException('parameter error: ' . $directory . ' is not a directory, please check it');
@@ -2768,7 +2783,9 @@ public function uploadDir($bucket, $prefix, $localDirectory, $exclude = '.|..|.s
27682783
self::OSS_PART_SIZE => self::OSS_MIN_PART_SIZE,
27692784
self::OSS_CHECK_MD5 => $checkMd5,
27702785
);
2771-
$realObject = (!empty($prefix) ? $prefix . '/' : '') . $item['file'];
2786+
//mbstring to utf-8
2787+
$fileName = $this->decodeFilePath($item['file']);
2788+
$realObject = (!empty($prefix) ? $prefix . '/' : '') . $fileName;
27722789

27732790
try {
27742791
$this->multiuploadFile($bucket, $realObject, $item['path'], $options);
@@ -3485,6 +3502,69 @@ private function getRegion()
34853502
return $this->region;
34863503
}
34873504

3505+
/**
3506+
* Encodes the file path from UTF-8 to GBK.
3507+
*
3508+
* @param $filepath
3509+
* @return string
3510+
*/
3511+
private function encodeFilePath($filepath)
3512+
{
3513+
if ($this->filePathCompatible !== true) {
3514+
return $filepath;
3515+
}
3516+
3517+
if (empty($filepath)) {
3518+
return $filepath;
3519+
}
3520+
3521+
try {
3522+
$encoding = array('UTF-8','GB2312', 'GBK');
3523+
$encode = mb_detect_encoding($filepath, $encoding);
3524+
if ($encode !== 'UTF-8') {
3525+
return $filepath;
3526+
}
3527+
$tmp = iconv($encode, 'GBK', $filepath);
3528+
if ($tmp !== false) {
3529+
$filepath = $tmp;
3530+
}
3531+
} catch (\Exception $e) {
3532+
//IGNORE
3533+
}
3534+
return $filepath;
3535+
}
3536+
3537+
/**
3538+
* Decodes the file path from GBK to UTF-8.
3539+
*
3540+
* @param $filepath
3541+
* @return string
3542+
*/
3543+
private function decodeFilePath($filepath)
3544+
{
3545+
if ($this->filePathCompatible !== true) {
3546+
return $filepath;
3547+
}
3548+
if (empty($filepath)) {
3549+
return $filepath;
3550+
}
3551+
3552+
try {
3553+
$encoding = array('UTF-8','GB2312', 'GBK');
3554+
$encode = mb_detect_encoding($filepath, $encoding);
3555+
if ($encode === 'UTF-8' || $encode === false) {
3556+
return $filepath;
3557+
}
3558+
$tmp = iconv($encode, 'UTF-8', $filepath);
3559+
if ($tmp !== false) {
3560+
$filepath = $tmp;
3561+
}
3562+
} catch (\Exception $e) {
3563+
//IGNORE
3564+
}
3565+
return $filepath;
3566+
}
3567+
34883568
/**
34893569
* Check if all dependent extensions are installed correctly.
34903570
* For now only "curl" is needed.
@@ -3702,4 +3782,6 @@ public function setConnectTimeout($connectTimeout)
37023782
private $signer;
37033783

37043784
private $checkObjectEncoding = false;
3785+
3786+
private $filePathCompatible;
37053787
}

tests/OSS/Tests/OssClientObjectTest.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace OSS\Tests;
44

55
use OSS\Core\OssException;
6+
use OSS\Core\OssUtil;
67
use OSS\OssClient;
78

89
require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php';
@@ -817,6 +818,86 @@ public function testObjectKeyWithNonUTF8Name()
817818
}
818819
}
819820

821+
public function testEncodeFilePath()
822+
{
823+
if (!OssUtil::isWin()) {
824+
$this->assertTrue(true);
825+
return;
826+
}
827+
828+
$fileFolder = __DIR__ . DIRECTORY_SEPARATOR . "中文目录";
829+
$filePath1 = $fileFolder . DIRECTORY_SEPARATOR . "中文文件名1.txt";
830+
$filePath2 = $fileFolder . DIRECTORY_SEPARATOR . "中文文件名2.txt";
831+
832+
$gbkfileFolder = iconv('UTF-8', 'GBK', $fileFolder);
833+
$gbkfilePath1 = iconv('UTF-8', 'GBK', $filePath1);
834+
$gbkfilePath2 = iconv('UTF-8', 'GBK', $filePath2);
835+
836+
$hexfilePath1 = bin2hex($filePath1);
837+
$hexGbkfilePath2 = bin2hex($gbkfilePath2);
838+
839+
//$this->assertEquals("e4b8ade69687e69687e4bbb6e5908d312e747874", $hexfilePath1);
840+
//$this->assertEquals("d6d0cec4cec4bcfec3fb322e747874", $hexGbkfilePath2);
841+
try {
842+
mkdir($fileFolder);
843+
} catch (\Exception $e) {
844+
}
845+
OssUtil::generateFile($filePath1, 200 * 1024);
846+
OssUtil::generateFile($filePath2, 202 * 1024);
847+
848+
try {
849+
$content1 = file_get_contents($filePath1);
850+
$content2 = file_get_contents($filePath2);
851+
852+
// upload file
853+
$this->ossClient->uploadFile($this->bucket, '123', $filePath1);
854+
$this->ossClient->uploadFile($this->bucket, '234', $gbkfilePath2);
855+
856+
$res = $this->ossClient->getObject($this->bucket, '123');
857+
$this->assertEquals($content1, $res);
858+
859+
$res = $this->ossClient->getObject($this->bucket, '234');
860+
$this->assertEquals($content2, $res);
861+
862+
// append file
863+
$position = $this->ossClient->appendFile($this->bucket, 'append-file', $filePath1, 0);
864+
$position = $this->ossClient->appendFile($this->bucket, 'append-file', $gbkfilePath2, $position);
865+
866+
$res = $this->ossClient->getObject($this->bucket, 'append-file');
867+
$this->assertEquals($content1.$content2, $res);
868+
869+
// multi paet
870+
$this->ossClient->multiuploadFile($this->bucket, 'multi-file-123', $filePath1, array(OssClient::OSS_PART_SIZE => 1));
871+
$this->ossClient->multiuploadFile($this->bucket, 'multi-file-234', $gbkfilePath2, array(OssClient::OSS_PART_SIZE => 1));
872+
$res = $this->ossClient->getObject($this->bucket, 'multi-file-123');
873+
$this->assertEquals($content1, $res);
874+
875+
$res = $this->ossClient->getObject($this->bucket, 'multi-file-234');
876+
$this->assertEquals($content2, $res);
877+
878+
// uploadDir
879+
$this->ossClient->uploadDir($this->bucket, "dir", $fileFolder);
880+
$options = array(
881+
'delimiter' => '',
882+
'prefix' => "dir",
883+
);
884+
$listObjectInfo = $this->ossClient->listObjects($this->bucket, $options);
885+
$objectList = $listObjectInfo->getObjectList();
886+
$this->assertEquals(2, count($objectList));
887+
$this->assertEquals('dir/中文文件名1.txt', $objectList[0]->getKey());
888+
$this->assertEquals('dir/中文文件名2.txt', $objectList[1]->getKey());
889+
890+
} catch (OssException $e) {
891+
$this->assertFalse(true);
892+
}
893+
894+
try {
895+
unlink($filePath1);
896+
unlink($filePath2);
897+
} catch (\Exception $e) {
898+
}
899+
}
900+
820901
protected function setUp(): void
821902
{
822903
parent::setUp();

0 commit comments

Comments
 (0)