PHP框架 Laravel

       现在因为公司需求,需要新开一个Laravel框架的项目,毫无疑问,我又被借调过去了,最近老是被借调,有点阴郁,不过反观来看,这也是好事,又可以复习和巩固一下自己的知识点,接下来开始讲解Laravel框架

1.安装(我使用的是composer安装)

安装命令1:

composer create-project laravel/laravel:^11.0 example-app(框架所在文件夹:安装时中午不必复制)

安装命令2:

composer global require laravel/installer
laravel new example-app(框架所在文件夹:安装时中午不必复制)

2.环境配置(.env文件)

应用名称

APP_NAME=Laravel


应用运行环境

APP_ENV=local


是否开启Debug模式

APP_DEBUG=true


数据库配置

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=root

3.框架启动:

cd example-app(框架所在文件夹:安装时中午不必复制)
php artisan serve




4.常用artisan命令:

1.显示您的应用配置、驱动程序和环境:php artisan about


2.加密环境文件(作用在.env文件): php artisan env:encrypt


3.解密环境文件(作用在.env文件):php artisan env:decrypt


4.框架启动:php artisan serve


5.这个命令会生成一个新的应用程序密钥,并将其自动添加到 .env 文件中:php artisan key:generate


6.创建一个新的控制器:php artisan make:controller


7.创建一个新的 Eloquent 模型:php artisan make:model


8.创建一个新的策略类:php artisan make:policy


9.创建一个新的种子文件:php artisan make:seeder


10.运行数据库迁移,创建或修改数据库表以匹配最新的迁移文件:php artisan migrate


11.回滚最后一个数据库迁移操作:php artisan migrate:rollback


12.重置并重新运行所有数据库迁移:php artisan migrate:refresh


13.列出应用程序的所有路由:php artisan route:list


14.清除应用程序缓存:php artisan cache:clear


15.创建配置缓存文件以加速应用程序的启动:php artisan config:cache


16.清除视图缓存:php artisan view:clear


17.清除优化文件:php artisan optimize:clear


18.启动一个与应用程序的交互式解释器:php artisan tinker


19.在本地开发服务器上运行应用程序:php artisan serve


20.生成未定义监听器的事件:php artisan event:generate


21.为通知表生成一个迁移文件:php artisan notification:table


22.为队列迁移生成一个迁移文件:php artisan queue:table


23.为会话迁移生成一个迁移文件:php artisan session:table


24.列出所有路由:php artisan route:list -v


25.创建中间件:php artisan make:middleware 中间件名
 

5.框架目录:

根目录

--app :应用程序的核心代码
--bootstrap :引导框架的 app.php 文件
--config :所有配置文件
--database :数据库迁移、模型工厂和种子文件
--public :包含 index.php 文件,这是所有请求进入您应用程序的入口点,并配置自动加载 
--resources :视图以及样式文件和JS文件
--routes :所有路由定义文件
--storage :日志、编译的 Blade 模板、基于文件的会话、文件缓存以及框架生成的其他文件
--tests :自动化测试
--vendor :Composer 依赖项

App目录 :大部分代码文件

--Broadcasting :所有广播频道类
--Console :所有自定义 Artisan 命令
--Exceptions :所有自定义异常
--Http :包含控制器、中间件和表单请求
--Jobs :包含应用程序的可队列化作业
--Listeners :处理事件的类
--Mail :代表电子邮件的类
--Models :所有的 Eloquent 模型类
--Notifications :应用程序发送的所有“事务性”通知
--Policies :应用程序的授权策略类
--Providers :应用程序的所有服务提供者
--Rules :应用程序的自定义验证规则对象


6.前端模

Blade

语法:
1.通过 {{ }} 渲染 PHP 变量(最常用)
2.通过 {!! !!} 渲染原生 HTML 代码(用于富文本数据渲染)
3.通过以 @ 作为前缀的 Blade 指令执行一些控制结构和继承、引入之类的操作
4.关键字:(关键字开始;关键字end结束)
    @if、@else、@elseif
    @unless(和 @if 条件相反的条)
    @isset、@empty
    @switch
    @for、@foreach 和 @while

Vue / React

react有函数式编码和类编码,这次讲的是的类编码,后面小编争取出一个函数式编码的文章

解决办法:
1.使用Inertia桥接了Laravel应用程序和Vue或React 前端之间的连接,允许使用Vue或React构建成熟的现代前端框架
引入相关类(版本需要升级到laravel9,php版本需要升级到php8):composer require inertiajs/inertia-php
2.直接引入相关资源(主要的JS文件:这样写其实是:穿着Blade的外衣的 Vue / React)

路由:

route::get('/reactest',[TestController::class,'reactst']);

头部:

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8" /><title>Hello React!</title><script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script><script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script><script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>

页面代码(包含异步请求):

@include('head')
<body>
<div id="example"></div>
<script type="text/babel">//请求主方法class UserGist extends React.Component {//构造函数(和后端的构造函数类似)constructor(props) {//super关键字实现调用父类,super代替的是父类的构建函数super(props);//控制组件的内部状态变化this.state = {username: '', lastGistUrl: ''};}//在组件挂载后立即调用(插入 DOM 树中)componentDidMount() {this.serverRequest = $.get(this.props.source, function (result) {var lastGist = result[0];this.setState({username: lastGist.owner.login,lastGistUrl: lastGist.html_url});}.bind(this));}//当组件即将被卸载/销毁时,会调用这个方法(和后端的析构函数类似)componentWillUnmount() {this.serverRequest.abort();}//渲染方法render() {return (<div>{this.state.username} 用户最新的 Gist 共享地址:<a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a></div>);}}//请求主体ReactDOM.render(//调用主方法(赋值请求地址)<UserGist source="https://api.github.com/users/octocat/gists" />,document.getElementById('example'));
</script>
</body>
</html>


7.路由:

use App\Http\Controllers\TestController;//框架路由测试
Route::get('/test', [TestController::class, 'index']);//控制器方法
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;class TestController extends BaseController
{public function index(){return view('test');}
}
?>//框架路由测试
Route::get('/test', [TestController::class, 'index']);//依赖注入
Route::get('/tests', function (Request $request) {//todo or 模板
});//指定请求方法
Route::match(['get', 'post'], '/', function () {//todo or 模板
});Route::any('/', function () {//todo or 模板
});Route::get('/testrequest', function (Request $request) {//todo or 模板
});//路由重定向
Route::redirect('/page1', '/page2');//单参数绑定
Route::get('/page3/{id}', function (string $id) {return '标记 '.$id;
});//多参数绑定
Route::get('/page4/{id}/{ids}', function (string $id,string $ids) {return '标记 '.$id.';新标记'.$ids;
});//可选参数(设置默认值)
Route::get('/page5/{name?}', function (?string $name = null) {return $name;
});//正则表达式(where 添加正则表达式)
Route::get('/page6/{name}', function (string $name) {// ...
})->where('name', '[A-Za-z]+');//路由重命名
Route::get('/page7', function () {// ...
})->name('page7realname');//路由组+中间件
Route::group(['prefix' => 'admin'],function () {Route::get('/page8', function () {//访问/admin/page8});Route::get('/page9', function () {//访问/admin/page9});
});//中间件(前置中间件,后置中间件,全局中间件)
php artisan make:middleware EnsureTokenIsValid//使用中间件Route::get('/page10', function () {//todo or 模板
})->middleware(EnsureTokenIsValid::class);//排除中间件Route::group(['prefix' => 'admin'],function () {Route::get('/page11', function () {//todo or 模板})->withoutMiddleware([EnsureTokenIsValid::class]);
});

8.(MVC)php代码:

M (Model)

<?phpnamespace App;use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;class Users extends Model
{//表protected $table = 'users';//组件protected $primaryKey = 'id';//主键自增是否开启public $incrementing = true;//主键 ID 的数据类型protected $keyType = 'int';//表示模型是否应该被打上时间戳public $timestamps = false;//数据库链接模型protected $connection = 'mysql';//定义方法public function phone(){return $this->hasOne(Users_extend::class);}
}

C (Controller)

<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Inertia\Inertia;
use Inertia\Response;class UserController extends Controller
{public function show(string $id): Response{return Inertia::render('Users/Profile', ['id' =>$id]);}
}?>

V (View)

<script setup>
import Layout from '@/Layouts/Authenticated.vue'
import { Head } from '@inertiajs/vue3'
const props = defineProps(['user'])
</script><template><Head title="User Profile" /><Layout><template #header><h2 class="text-xl font-semibold leading-tight text-gray-800">vue测试</h2></template><div class="py-12">标识: {{$id}}</div></Layout>
</template>

写到这里,相信大家已经了解到了,控制器、视图大家都已经学会了,后面我们开始进阶的用法

数据库(数据库配置在.env文件中):

9.数据库 (原生 + Eloquent)


//访问路由
Route::get('/datacreate', [TestController::class, 'data_create']);
Route::get('/datafind', [TestController::class, 'data_find']);
Route::get('/datafinds', [TestController::class, 'data_finds']);
Route::get('/datafindspage', [TestController::class, 'data_finds_page']);
Route::get('/datafindshasone', [TestController::class, 'data_finds_hasone']);
Route::get('/dataup', [TestController::class, 'data_up']);
use Illuminate\Support\Facades\DB;
//数据库连接
'mysql' => ['read' => ['host' => ['192.168.1.1','196.168.1.2',],],'write' => ['host' => ['196.168.1.3',],],'sticky' => true,'database' => env('DB_DATABASE', 'forge'),'username' => env('DB_USERNAME', 'forge'),'password' => env('DB_PASSWORD', ''),'unix_socket' => env('DB_SOCKET', ''),'charset' => env('DB_CHARSET', 'utf8mb4'),'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),'prefix' => '','prefix_indexes' => true,'strict' => true,'engine' => null,'options' => extension_loaded('pdo_mysql') ? array_filter([PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),]) : [],
],
//数据库Eloquent组件
use Illuminate\Database\Eloquent\Model;//创建model
php artisan make:model Users//model方法
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
class Users extends Model
{//表protected $table = 'users';//组件protected $primaryKey = 'id';//主键自增是否开启public $incrementing = true;//主键 ID 的数据类型protected $keyType = 'int';//表示模型是否应该被打上时间戳public $timestamps = false;//数据库链接模型protected $connection = 'mysql';//定义方法public function phone(){return $this->hasOne(Users_extend::class);}
}//创建model
php artisan make:model Users_extend//model方法
namespace App;
use Illuminate\Database\Eloquent\Model;
class Users_extend extends Model
{//表protected $table = 'user_extend';//定义方法public function user(){return $this->belongsTo(Users::class);}
}//方法调用
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
//数据库
use App\Users;class TestController extends BaseController
{//初始化public function __construct(){$this->student = new Users();}//数据创建public function data_create(){$this->student->username='数据测试';$this->student->sex="女";$this->student->age="30";$this->student->save();$userid = $this->student->id;var_dump($userid);die;}//数据查询public function data_find(){$result = $this->student->where("id",5)->first();var_dump($result);die;}//数据查询public function data_finds(){$result = $this->student::all();var_dump($result);die;}//数据分页public function data_finds_page(){$result = $this->student::paginate(2);var_dump($result);die;}//数据一对一(hasone)public function data_finds_hasone(){$phone = $this->student::find(1)->phone;var_dump($phone);die;}//数据修改public function data_up(){$result = $this->student->where("id","=","5")->update(['username'=>"数据测试编号5"]);var_dump($result);die;}
}

10.关联关系(相当于联合查询)

 一对一

return $this->hasOne();
return $this->belongsTo();


一对多

return $this->hasMany();
return $this->belongsTo();


多对多

return $this->belongsToMany();
return $this->belongsToMany();


11.文件上传表单


<form id="uploadForm" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="submit" value="上传" />
</form>

//异步方法
<script>
    $(document).ready(function (e) {
            $('#uploadForm').on('submit', function(e) {
                    e.preventDefault(); // 阻止表单默认提交行为
                    var formData = new FormData(this); // 创建FormData对象
     
                    $.ajax({
                            type: 'POST',
                            url: '/upload', // 这里是你的上传处理路径
                            data: formData,
                            contentType: false,
                            processData: false,
                            success: function(response) {
                                    console.log(response); // 处理成功的回调
                            },
                            error: function() {
                                    console.log('上传失败'); // 处理错误的回调
                            }
                    });
            });
    });
</script>


普通文件上传

use Illuminate\Support\Facades\Route;
Route::post('/upload', function () {request()->file('file')->store('files', 'public');return '文件上传成功!';
});

oss文件上传

<?php
use App\Http\Controllers\Core\ApiController;
use App\Models\LoginLog;
use Illuminate\Http\Request;
use OSS\OssClient;//定义方法
class FileController extends ApiController
{//上传主方法public function uploadFile(Request $request){//获取上传文件$file = $request->file();//上传方法调用$ret = $this->_upload($file);//参数返回echo json_encode($ret);exit;}//上传方法protected function _upload($file){//获取上传文件名字$dir_name = empty($_GET['dir']) ? 'image' : trim($_GET['dir']);//获取路径(配置文件中获取)$storage_path = config('upload.storage');$webpath_path = config('upload.webpath');//重名民上传文件$image_path =  $dir_name . '/' . date("Y-m") . '/';//获取路径(配置文件中获取)$app_url = env('APP_URL') . '/';//判断上传文件是否存在if (!$file) {return array('error'=>1,'message'=>"文件上传失败,请检查后重试");}//获取路径(配置文件中获取)$ossConfig = config('oss.' . config('upload.ossflag'));if($ossConfig['bucket_addr']) {$app_url = $ossConfig['bucket_addr'];}//文件上传$tmpName = $file->getPathName();$fileExtension = $file->getClientOriginalExtension();$filePath = md5_file($tmpName) . '.' . $fileExtension;//判断文件大小$file_size = $file->getSize();if($file_size > config('upload.maxSize')){return array('error'=>1,'message'=>"文件不可以超过50MB");}//判断是否符合上传类型if (!in_array(strtolower($fileExtension),config('upload.allowExts'))){return array('error'=>1,'message'=>"文件类型不支持");}//上传成功后处理if(config('oss.' . 'oss_open') == 1) {//初始化OSS对象$oss = new OssClient($ossConfig['access_key_id'], $ossConfig['access_key_secret'], $ossConfig['endpoint']);//oss上传$res = $oss->uploadFile($ossConfig['bucket'],$webpath_path . $image_path . $filePath,$v->getPathName());if ($res){$data['oss'] = 1;$data['attach_url'] = $ossConfig['bucket_addr'] . $webpath_path . $image_path . $filePath;} else {$data['attach_url'] = $app_url . $webpath_path . $image_path . $filePath;$data['oss'] = 0;}$data['time'] = time();} else {$data['oss'] = 0;$data['attach_url'] = $app_url. $webpath_path . $image_path . $filePath;$data['time'] = time();}if(!$data['oss'] || config('oss.' . 'is_delete') != 1){$file->move($storage_path . $image_path, $filePath);    unset($data);}return array('error'=>0,'url'=>$data['attach_url']);}
}


        讲到这里基础的部分就已经完成了,万米高楼平地起,先复习到这里,先赶着做项目去了,后面高级一点的广播、缓存、集合、上下文啥的,后面有机会再出一个学习文章供大家学习

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/333579.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数组基础-笔记

数组是非常基础的数据结构&#xff0c;实现运用和理解是两回事 数组是存放在连续内存空间上的相同类型的数据的集合 可以方便的通过下表索引的方式获取到下标下对应的数据。 举一个字符数组的例子&#xff1a; 注意两点&#xff1a; 数组下标从0开始 数组内存空间的地址是连…

yarn dev启动项目时遇到的问题

用yarn dev启动项目的时候&#xff0c;遇到了如下问题&#xff1a; 这个时候&#xff0c;我们可以这样解决&#xff1a;用nvm list 看下已安装的node版本&#xff0c;用nvm use切换一下node版本&#xff0c;当然前提是你已经安装了nvm。

C++: 二叉搜索树及实现

目录 一、二叉搜索树的概念 二、二叉搜索树的操作 2.1插入 2.2删除 1.有左子树&#xff0c;无右子树 2.有右子树&#xff0c;无左子树 3.有左子树和右子树 三、二叉搜索树的实现 要点 前言&#xff1a;为了学习map和set&#xff0c;需要先学二叉搜索树作为铺垫。 一、…

[论文笔记]Chain-of-Thought Prompting Elicits Reasoning in Large Language Models

引言 今天带来思维链论文 Chain-of-Thought Prompting Elicits Reasoning in Large Language Models的笔记。 作者探索了如何通过生成一系列中间推理步骤的思维链&#xff0c;显著提升大型语言模型在进行复杂推理时的能力。 1 总体介绍 语言模型的规模扩大已被证明能够带来…

[数据集][目标检测]伤口检测数据集VOC+YOLO格式2760张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2760 标注数量(xml文件个数)&#xff1a;2760 标注数量(txt文件个数)&#xff1a;2760 标注…

课时138:变量进阶_变量实践_综合案例

2.1.3 综合案例 学习目标 这一节&#xff0c;我们从 免密认证、脚本实践、小结 三个方面来学习 免密认证 案例需求 A 以主机免密码认证 连接到 远程主机B我们要做主机间免密码认证需要做三个动作1、本机生成密钥对2、对端机器使用公钥文件认证3、验证手工演示 本地主机生成…

调整GIF图大小的方法是什么?分享4个

调整GIF图大小的方法是什么&#xff1f;在数字化时代&#xff0c;GIF以其独特的动图魅力&#xff0c;成为了网络交流中不可或缺的一部分。无论是社交媒体、博客文章还是工作汇报&#xff0c;一个恰到好处的GIF图往往能有效吸引观众的注意&#xff0c;传递信息&#xff0c;但过大…

YOLOv8+PyQt5面部表情检测系统完整资源集合(yolov8模型,从图像、视频和摄像头三种路径识别检测,包含登陆页面、注册页面和检测页面)

1.资源包含可视化的面部表情检测系统&#xff0c;基于最新的YOLOv8训练的面部表情检测模型&#xff0c;和基于PyQt5制作的可视化面部表情检测系统&#xff0c;包含登陆页面、注册页面和检测页面&#xff0c;该系统可自动检测和识别图片或视频当中出现的八类面部表情&#xff1a…

3D开发工具HOOPS在BIM系统中的应用

建筑信息模型是一种革命性的建筑设计、施工和管理方法。它通过创建和利用数字信息来优化建筑项目的设计、施工和运营过程。在这个过程中&#xff0c;3D开发工具HOOPS扮演着至关重要的角色&#xff0c;为BIM系统提供了强大的技术支持和丰富的功能。HOOPS中文网http://techsoft3d…

ThreadLocal简介

Thread类中&#xff0c;有个ThreadLocal.ThreadLocalMap 的成员变量。 ThreadLocalMap内部维护了Entry数组&#xff0c;每个Entry代表一个完整的对象&#xff0c;key是ThreadLocal本身&#xff0c;value是ThreadLocal的泛型对象值 public void set(T value) {Thread t Thread…

前端开发之xlsx的使用和实例,并导出多个sheet

前端开发之xlsx的使用和实例 前言效果图1、安装2、在页面中引用3、封装工具类&#xff08;excel.js&#xff09;4、在vue中使用 前言 在实现业务功能中导出是必不可少的功能&#xff0c;接下来为大家演示在导出xlsx的时候的操作 效果图 1、安装 npm install xlsx -S npm inst…

Android HAL到Framework

一、为什么需要Framwork? Framework实际上是⼀个应⽤程序的框架&#xff0c;提供了很多服务&#xff1a; 1、丰富⽽⼜可扩展的视图&#xff08;Views&#xff09;&#xff0c; 可以⽤来构建应⽤程序&#xff0c;它包括列表&#xff08;lists&#xff09;&#xff0c;⽹格&am…

代码随想录算法训练营第20天 |● 654.最大二叉树 ● 617.合并二叉树 ● 700.二叉搜索树中的搜索 ● 98.验证二叉搜索树

文章目录 前言654.最大二叉树思路方法一 递归法方法一2 老师的优化递归法 617.合并二叉树思路方法一 递归法方法二 迭代法 700.二叉搜索树中的搜索思路方法一 递归法方法二 迭代法 98.验证二叉搜索树思路方法一 使用数组方法二 不使用数组代码注意点&#xff1a; 方法二 使用双…

SecureCRT for Mac注册激活版:专业终端SSH工具

SecureCRT是一款支持SSH&#xff08;SSH1和SSH2&#xff09;的终端仿真程序&#xff0c;简单地说是Windows下登录UNIX或Linux服务器主机的软件。 SecureCRT支持SSH&#xff0c;同时支持Telnet和rlogin协议。SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的理想工具。通过…

零售EDI:Target DVS EDI项目案例

Target塔吉特是美国一家巨型折扣零售百货集团&#xff0c;与全球供应商建立长远深入的合作关系&#xff0c;目前国内越来越多的零售产品供应商计划入驻Target。完成入驻资格审查之后&#xff0c;Target会向供应商提出EDI对接邀请&#xff0c;企业需要根据指示完成供应商EDI信息…

Vue学习笔记3——事件处理

事件处理 1、事件处理器&#xff08;1&#xff09;内联事件处理器&#xff08;2&#xff09;方法事件处理器 2、事件参数3、事件修饰符 1、事件处理器 我们可以使用v-on 指令(简写为)来监听DOM事件&#xff0c;并在事件触发时执行对应的JavaScript。 用法: v-on:click"me…

[自动驾驶技术]-6 Tesla自动驾驶方案之硬件(AI Day 2021)

1 硬件集成 特斯拉自动驾驶数据标注过程中&#xff0c;跨250万个clips超过100亿的标注数据&#xff0c;无论是自动标注还是模型训练都要求具备强大的计算能力的硬件。下图是特斯拉FSD计算平台硬件电路图。 1&#xff09;神经网络编译器 特斯拉AI编译器主要针对PyTorch框架&am…

【面试必看】Java并发

并发 1. 线程 1. 线程vs进程 进程是程序的一次执行过程&#xff0c;是系统运行程序的基本单位&#xff0c;因此进程是动态的。 系统运行一个程序即是一个进程从创建&#xff0c;运行到消亡的过程。在 Java 中&#xff0c;当我们启动 main 函数时其实就是启动了一个 JVM 的进…

java文档管理系统的设计与实现源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的文档管理系统的设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 文档管理系统的…

初学C语言100题:经典例题节选(源码分享)

1.打印Hello World! #include <stdio.h>int main() {printf("hello world\n");//使用printf库函数 注意引用头文件return 0; } 2.输入半径 计算圆的面积 int main() {float r, s;//定义变量scanf("%f", &r);//输入半径s 3.14 * r * r;// 圆的…