在 Yii 2.0 中实现:资源服务(复制来源的资源文件至渠道发布的存储目录,返回相对路径)
1、配置文件:\common\config\params-local.php,自媒体为来源
// 自媒体 'spider' => [ 'asset' => [ // 资源 'image' => [ // 图片 'hostInfo' => 'http://localhost/channel-pub-api/storage/spider', // HOME URL 'baseUrl' => '/images', // BASE URL 'basePath' => 'E:/wwwroot/channel-pub-api/storage/spider/images', // BASE PATH ], 'video' => [ // 视频 'hostInfo' => 'http://localhost/channel-pub-api/storage/spider', // HOME URL 'baseUrl' => '/videos', // BASE URL 'basePath' => 'E:/wwwroot/channel-pub-api/storage/spider/videos', // BASE PATH ], ], ], // 渠道发布接口 'channelPubApi' => [ 'asset' => [ // 资源 'image' => [ // 图片 'basePath' => 'E:/wwwroot/channel-pub-api/storage/channel-pub-api/images', // BASE PATH ], 'video' => [ // 视频 'basePath' => 'E:/wwwroot/channel-pub-api/storage/channel-pub-api/videos', // BASE PATH ], ], ],
2、新建服务类,\common\services\AssetService.php,实现静态方法:copyAssets
<?php /** * Created by PhpStorm. * User: WangQiang * Date: 2018/09/20 * Time: 14:04 */ namespace common\services; use Yii; use yii\base\Model; use common\logics\ChannelAppSource; use yii\db\ActiveRecordInterface; use yii\helpers\StringHelper; use yii\helpers\FileHelper; use yii\web\NotFoundHttpException; use yii\web\UnprocessableEntityHttpException; use yii\web\ServerErrorHttpException; use yii\web\HttpException; /** * 资源服务 * * @author Qiang Wang <shuijingwanwq@163.com> * @since 1.0 */ class AssetService extends Service { /** * 复制来源的资源文件至渠道发布的资源目录,返回相对路径 * @param string $source 来源 * 格式如下:spider * @param array $assets 来源的资源文件的绝对URL * 格式如下: * [ * [ * 'type' => 'image', * 'absolute_url' => 'http://localhost/channel-pub-api/storage/spider/images/1.png', * ], * [ * 'type' => 'video', * 'absolute_url' => 'http://localhost/channel-pub-api/storage/spider/videos/7月份北上广深等十大城市租金环比上涨 看东方 20180820 高清_高清.mp4', * ], * ] * * @return array $channelPubApiAssetAbsolutePaths 渠道发布的资源文件的相对路径 * 格式如下: * [ * [ * 'type' => 'image', * 'relative_path' => '/2018/09/20/1537439889.2333.1441541478.png', * ], * [ * 'type' => 'video', * 'relative_path' => '/2018/09/20/1537439889.2403.62871268.mp4', * ], * ] * * @throws UnprocessableEntityHttpException 如果来源的资源文件不是以来源的 HOME URL + BASE URL 开头,将抛出 422 HTTP 异常 * @throws NotFoundHttpException 如果来源的资源文件不存在,将抛出 404 HTTP 异常 * @throws ServerErrorHttpException 如果创建目录失败,将抛出 500 HTTP 异常 * @throws ServerErrorHttpException 如果复制来源的资源文件至渠道发布的资源目录失败,将抛出 500 HTTP 异常 * @throws \yii\base\Exception if the directory could not be created (i.e. php error due to parallel changes) */ public static function copyAssets($source, $assets) { // 不是以来源的 HOME URL + BASE URL 开头的来源的资源文件 $notAbsoluteUrlStartKeys = []; // 不存在的来源的资源文件 $notExistsKeys = []; // 渠道发布的资源文件的相对路径 $channelPubApiAssetAbsolutePaths = []; foreach ($assets as $key => $asset) { // 检查来源的资源文件的绝对URL是否以来源的 HOME URL + BASE URL 开头 if (!StringHelper::startsWith($asset['absolute_url'], Yii::$app->params[$source]['asset'][$asset['type']]['hostInfo'] . Yii::$app->params[$source]['asset'][$asset['type']]['baseUrl'])) { $notAbsoluteUrlStartKeys[] = $key; } else { // 获取来源的资源文件的绝对路径 $sourceAssetAbsolutePath = Yii::$app->params[$source]['asset'][$asset['type']]['basePath'] . str_replace(Yii::$app->params[$source]['asset'][$asset['type']]['hostInfo'] . Yii::$app->params[$source]['asset'][$asset['type']]['baseUrl'], '', $asset['absolute_url']); // 检查来源的资源文件是否存在 if (!file_exists($sourceAssetAbsolutePath)) { $notExistsKeys[] = $key; } } } if (!empty($notAbsoluteUrlStartKeys)) { $notAbsoluteUrlStartKeys = implode(",", $notAbsoluteUrlStartKeys); throw new UnprocessableEntityHttpException(Yii::t('common/error', Yii::t('common/error', Yii::t('common/error', '35003'), ['not_absolute_url_start_keys' => $notAbsoluteUrlStartKeys])), 35003); } if (!empty($notExistsKeys)) { $notExistsKeys = implode(",", $notExistsKeys); throw new NotFoundHttpException(Yii::t('common/error', Yii::t('common/error', Yii::t('common/error', '35004'), ['not_exists_keys' => $notExistsKeys])), 35004); } foreach ($assets as $key => $asset) { // 获取来源的资源文件的绝对路径 $sourceAssetAbsolutePath = Yii::$app->params[$source]['asset'][$asset['type']]['basePath'] . str_replace(Yii::$app->params[$source]['asset'][$asset['type']]['hostInfo'] . Yii::$app->params[$source]['asset'][$asset['type']]['baseUrl'], '', $asset['absolute_url']); // 获取来源的资源文件的路径信息 $pathInfo = pathinfo($sourceAssetAbsolutePath); // 渠道发布的资源文件的相对路径 $directory = date('Y/m/d'); $channelPubApiAssetRelativePath = '/' . $directory . '/' . microtime(true) . '.' . mt_rand() . '.' . $pathInfo['extension']; // 渠道发布的资源文件的绝对路径 $channelPubApiAssetAbsolutePath = Yii::$app->params['channelPubApi']['asset'][$asset['type']]['basePath'] . $channelPubApiAssetRelativePath; // 创建目录 if (!FileHelper::createDirectory(Yii::$app->params['channelPubApi']['asset'][$asset['type']]['basePath'] . '/' . $directory)) { throw new ServerErrorHttpException(Yii::t('common/error', Yii::t('common/error', Yii::t('common/error', '35005'), ['directory' => Yii::$app->params['channelPubApi']['asset'][$asset['type']]['basePath'] . '/' . $directory])), 35005); } // 复制来源的资源文件至渠道发布的资源目录 if (!copy($sourceAssetAbsolutePath, $channelPubApiAssetAbsolutePath)) { throw new ServerErrorHttpException(Yii::t('common/error', Yii::t('common/error', Yii::t('common/error', '35006'), ['source_asset_absolute_path' => $sourceAssetAbsolutePath])), 35006); } $channelPubApiAssetAbsolutePaths[$key] = [ 'type' => $asset['type'], 'relative_path' => $channelPubApiAssetRelativePath, ]; } return $channelPubApiAssetAbsolutePaths; } }
3、引用服务类,\common\services\AssetService.php,调用静态方法:copyAssets
$assets = [ [ 'type' => 'image', 'absolute_url' => 'http://localhost/channel-pub-api/storage/spider/images/1.png', ], [ 'type' => 'video', 'absolute_url' => 'http://localhost/channel-pub-api/storage/spider/videos/7月份北上广深等十大城市租金环比上涨 看东方 20180820 高清_高清.mp4', ], ]; $assetServiceResult = AssetService::copyAssets('spider', $assets); print_r($assetServiceResult); exit;
4、运行方法之后,打印出 $assetServiceResult
Array ( [0] => Array ( [type] => image [relative_path] => /2018/09/21/1537495742.6172.473015079.png ) [1] => Array ( [type] => video [relative_path] => /2018/09/21/1537495742.6251.651458618.mp4 ) )
5、查看复制后的目录与文件,符合预期,如图1
6、升级至开发环境(CentOS)后,复制文件成功,如图2
近期评论