rafaelwendel / phpsupabase
PHPSupabase 是用 PHP 语言编写的库,它允许您通过与其 Rest API 集成来使用在 Supabase(https://supabase.io)中创建的项目资源。
Requires
- guzzlehttp/guzzle: ^7.0
README
PHPSupabase 是用 PHP 语言编写的库,它允许您通过与其 Rest API 集成来使用在 Supabase(https://supabase.io)中创建的项目资源。
内容
关于 Supabase
Supabase 是 "开源 Firebase 的替代品"。通过它,可以在不到 2 分钟的时间内创建后端。从 Postgres 数据库、身份验证、即时 API、实时订阅和存储开始您的项目。
PHPSupabase 特点
- 创建和管理 Supabase 项目的用户
- 管理用户身份验证(通过电子邮件/密码、魔法链接等)
- 在 Postgres 数据库中插入、更新、删除和获取数据(通过 Supabase 项目的 Rest API)
- QueryBuilder 类以简单的方式过滤项目数据
安装与加载
PHPSupabase 可在 Packagist 上找到,并且通过 Composer 安装是推荐的方式。将以下行添加到您的 composer.json
文件中
"rafaelwendel/phpsupabase" : "^0.0.1"
或者运行
composer require rafaelwendel/phpsupabase
如何使用
要使用 PHPSupabse 库,您必须在 Supabase 控制面板中有一个账户和一个项目。在项目设置(API 部分)中,您应该记下您项目的 API密钥
和 URL
。 (注意:基本上我们有两个用于 URL 的后缀:/rest/v1
和 /auth/v1
,但自版本 0.0.5
以来,这些后缀中之一的定义是可选的)
首先,让我们实例化 Service()
类。我们必须在构造函数中传递 API密钥
和 url
。
<?php require "vendor/autoload.php"; $service = new PHPSupabase\Service( "YOUR_API_KEY", "https://aaabbbccc.supabase.co" ); //In versions 0.0.4 or earlier it is necessary to set the suffix $service = new PHPSupabase\Service( "YOUR_API_KEY", "https://aaabbbccc.supabase.co/auth/v1" // or https://aaabbbccc.supabase.co/rest/v1 );
Service
类抽象了与项目 API 的操作,同时也提供了其他类的实例(Auth
、Database
和 QueryBuilder
)。
Auth 类
让我们实例化 Auth
类的对象
$auth = $service->createAuth();
$auth
对象有几种用于管理项目用户的方法。通过它,可以创建新用户或验证现有用户的登录。
使用电子邮件和密码创建新用户
以下是如何使用 email
和 password
创建新用户的示例。
$auth = $service->createAuth(); try{ $auth->createUserWithEmailAndPassword('newuser@email.com', 'NewUserPassword'); $data = $auth->data(); // get the returned data generated by request echo 'User has been created! A confirmation link has been sent to the '. $data->email; } catch(Exception $e){ echo $auth->getError(); }
新创建的用户现在在项目的用户表中,可以在 Supabase 控制面板的 "身份验证" 部分中看到。要启用,用户必须访问发送到电子邮件的确认链接。
在 createUserWithEmailAndPassword
方法的第三个参数中,您可以传递包含要保存的 user_metadata
的数组(例如:name
和 age
)。
$user_metadata = [ 'name' => 'Lebron James', 'age' => '34' ]; $auth->createUserWithEmailAndPassword('lebron@email.com', 'LebronPassword', $user_metadata);
使用电子邮件和密码登录
现在让我们看看如何进行用户认证。认证请求返回一个access_token
(Bearer Token),可以在以后的操作中使用,并检查过期时间。此外,还会返回其他信息,如refresh_token
和用户数据。无效的登录凭据会导致抛出一个新的异常。
$auth = $service->createAuth(); try{ $auth->signInWithEmailAndPassword('user@email.com', 'UserPassword'); $data = $auth->data(); // get the returned data generated by request if(isset($data->access_token)){ $userData = $data->user; //get the user data echo 'Login successfully for user ' . $userData->email; //save the $data->access_token in Session, Cookie or other for future requests. } } catch(Exception $e){ echo $auth->getError(); }
获取登录用户的资料
要获取用户数据,您需要拥有在登录操作中返回的access_token
(Bearer Token)。
$auth = $service->createAuth(); $bearerToken = 'THE_ACCESS_TOKEN'; try{ $data = $auth->getUser($bearerToken); print_r($data); // show all user data returned } catch(Exception $e){ echo $auth->getError(); }
更新用户资料
可以更新用户数据(如电子邮件和密码),还可以创建/更新metadata
,这是我们可以创建的附加数据(如first_name
、last_name
、instagram_account
或其他)。
updateUser
方法必须以bearerToken
作为参数。除了它之外,我们还有三个可选参数:email
、password
和data
(数组)。如果您不想更改这些数据中的某些数据,只需将其设置为null
。
以下是一个保存/更新用户两个新元数据(first_name
和last_name
)的示例。
$auth = $service->createAuth(); $bearerToken = 'THE_ACCESS_TOKEN'; $newUserMetaData = [ 'first_name' => 'Michael', 'last_name' => 'Jordan' ]; try{ //the parameters 2 (email) and 3(password) are null because this data will not be changed $data = $auth->updateUser($bearerToken, null, null, $newUserMetaData); print_r($data); // show all user data returned } catch(Exception $e){ echo $auth->getError(); }
请注意,在现在返回的数组中,已将first_name
和last_name
键添加到user_metadata
中。
数据库类
Database类提供了执行对Supabase项目提供的Postgre数据库表的操作(插入、更新、删除和获取)的功能。
对于下面的示例,请考虑以下数据库结构
categories (id INT AUTO_INCREMENT, categoryname VARCHAR(32)) products (id INT AUTO_INCREMENT, productname VARCHAR(32), price FLOAT, categoryid INT)
Database类也是从service
对象实例化的。您必须传递将要使用的table
及其相应的主键(通常是id
)。
让我们创建一个对象来处理categories
表
$db = $service->initializeDatabase('categories', 'id');
通过db
变量可以执行对categories
表的操作。
注意:如果使用表中启用了行级安全(RLS),则将bearerToken
传递给Service
对象
$bearerToken = 'THE_ACCESS_TOKEN'; //returned in the login action. $db = $service->setBearerToken($bearerToken)->initializeDatabase('categories', 'id');
插入数据
在categories
表中插入新记录
$db = $service->initializeDatabase('categories', 'id'); $newCategory = [ 'categoryname' => 'Video Games' ]; try{ $data = $db->insert($newCategory); print_r($data); //returns an array with the new register data /* Array ( [0] => stdClass Object ( [id] => 1 [categoryname] => Video Games ) ) */ } catch(Exception $e){ echo $e->getMessage(); }
现在让我们插入一个来自分类1 - Video Games
的新产品
$db = $service->initializeDatabase('products', 'id'); $newProduct = [ 'productname' => 'XBOX Series S', 'price' => '299.99', 'categoryid' => '1' //Category "Video Games" ]; try{ $data = $db->insert($newProduct); print_r($data); //returns an array with the new register data /* Array ( [0] => stdClass Object ( [id] => 1 [productname] => XBOX Series S [price] => 299.99 [categoryid] => 1 ) ) */ } catch(Exception $e){ echo $e->getMessage(); }
更新数据
要更新数据库中的记录,我们使用update
方法,将待更新的记录的id
(PK)作为参数传递,以及包含新数据的array
(注意:目前无法使用除主键之外的其他参数执行更新)。
在下面的示例中,我们将更新具有id=1
的产品("Xbox Series S"更改为"XBOX Series S 512GB"和"299.99"更改为"319.99")的productname
和price
。
$db = $service->initializeDatabase('products', 'id'); $updateProduct = [ 'productname' => 'XBOX Series S 512GB', 'price' => '319.99' ]; try{ $data = $db->update('1', $updateProduct); //the first parameter ('1') is the product id print_r($data); //returns an array with the product data (updated) /* Array ( [0] => stdClass Object ( [id] => 1 [productname] => XBOX Series S 512GB [price] => 319.99 [categoryid] => 1 ) ) */ } catch(Exception $e){ echo $e->getMessage(); }
删除数据
要从表中删除记录,只需调用delete
方法,并将待删除记录的id
(PK)作为参数传递。
以下代码删除了products
表中的id=1
的产品
$db = $service->initializeDatabase('products', 'id'); try{ $data = $db->delete('1'); //the parameter ('1') is the product id echo 'Product deleted successfully'; } catch(Exception $e){ echo $e->getMessage(); }
获取数据
在Database
类中提供了以下方法来获取数据
fetchAll()
:获取所有表记录;findBy(string $column, string $value)
:按列/值(使用=
运算符)获取过滤记录;findByLike(string $column, string $value)
:按列/值(使用LIKE
运算符)获取过滤记录;join(string $foreignTable, string $foreignKey)
:在设置的表和另一个相关表之间创建join
并获取记录;createCustomQuery(array $args)
:构建自定义SQL查询。以下keys
对args
参数有效select
from
join
where
limit
range
所有上述方法都返回Database
类的自实例。要访问获取到的数据,请调用getResult
方法。
查看一些示例
$db = $service->initializeDatabase('products', 'id'); try{ $listProducts = $db->fetchAll()->getResult(); //fetch all products foreach ($listProducts as $product){ echo $product->id . ' - ' . $product->productname . '($' . $product->price . ') <br />'; } } catch(Exception $e){ echo $e->getMessage(); }
现在,使用findBy
方法的一个示例
$db = $service->initializeDatabase('products', 'id'); try{ $listProducts = $db->findBy('productname', 'PlayStation 5')->getResult(); //Searches for products that have the value "PlayStation 5" in the "productname" column foreach ($listProducts as $product){ echo $product->id . ' - ' . $product->productname . '($' . $product->price . ') <br />'; } } catch(Exception $e){ echo $e->getMessage(); }
搜索products
并添加与categories
表的连接
$db = $service->initializeDatabase('products', 'id'); try{ $listProducts = $db->join('categories', 'id')->getResult(); //fetch data from "products" JOIN "categories" foreach ($listProducts as $product){ //SHOW "productname" - "categoryname" echo $product->productname . ' - ' . $product->categories->categoryname . '<br />'; } } catch(Exception $e){ echo $e->getMessage(); }
搜索所有价格(price
大于200.00
)的id
、productname
和price
的所有products
的自定义查询示例,"JOIN" categories
过滤
$db = $service->initializeDatabase('products', 'id'); $query = [ 'select' => 'id,productname,price', 'from' => 'products', 'join' => [ [ 'table' => 'categories', 'tablekey' => 'id' ] ], 'where' => [ 'price' => 'gt.200' //"gt" means "greater than" (>) ] ]; try{ $listProducts = $db->createCustomQuery($query)->getResult(); foreach ($listProducts as $product){ echo $product->id . ' - ' . $product->productname . '($' . $product->price . ') <br />'; } } catch(Exception $e){ echo $e->getMessage(); }
自定义查询的其他示例
//products with price > 200 AND productname LIKE '%n%' $query = [ 'select' => 'id,productname,price', 'from' => 'products', 'where' => [ 'price' => 'gt.200', //"gt" means "greater than" (>) 'productname' => 'like.%n%' //like operator ] ]; //products with categoryid = 1 $query = [ 'select' => 'id,productname,price', 'from' => 'products', 'where' => [ 'categoryid' => 'eq.1', //"eq" means "equal" (=) ] ]; //products with price < 1000 LIMIT 4 results $query = [ 'select' => 'id,productname,price', 'from' => 'products', 'where' => [ 'price' => 'lt.1000', //"lt" means "less than" (<) ], 'limit' => 4 //4 first rows ];
比较运算符
可用于where
子句的主要运算符
eq
:等于neq
:不等于gt
:大于gte
:大于等于lt
:小于lte
:小于等于like
:在列中搜索指定的模式ilike
:在列中搜索指定的模式(不区分大小写)
其他可用运算符
is
in
cs
cd
sl
sr
nxl
nxr
adj
ov
fts
plfts
phfts
wfts
not.eq
not.neq
not.gt
not.gte
not.lt
not.lte
not.like
not.ilike
not.is
not.in
not.cs
not.cd
not.sl
not.sr
not.nxl
not.nxr
not.adj
not.ov
not.fts
not.plfts
not.phfts
not.wfts
QueryBuilder 类
QueryBuilder类提供动态构建SQL查询的方法。它从service
对象实例化。
$query = $service->initializeQueryBuilder();
注意:如果任何使用的表启用了行级安全(RLS),则将bearerToken
传递给Service
对象
$bearerToken = 'THE_ACCESS_TOKEN'; //returned in the login action. $query = $service->setBearerToken($bearerToken)->initializeQueryBuilder();
可用方法
select(string $select)
:字段(以逗号分隔)或*
from(string $from)
:表join(string $table, string $tablekey, string $select = null)
:相关表where(string $column, string $value)
:条件limit(int $limit)
:限制行数order(string $order)
:排序字段range(string $range)
:结果范围(例如:“0-3”)
所有提到的方法都返回QueryBuilder类的自身实例。要运行挂载的查询,请调用execute方法。然后,要访问检索到的数据,请调用getResult方法。
从products
表获取所有数据的示例
$query = $service->initializeQueryBuilder(); try{ $listProducts = $query->select('*') ->from('products') ->execute() ->getResult(); foreach ($listProducts as $product){ echo $product->id . ' - ' . $product->productname . '($' . $product->price . ') <br />'; } } catch(Exception $e){ echo $e->getMessage(); }
从products
"JOIN" categories
获取所有数据的示例
$query = $service->initializeQueryBuilder(); try{ $listProducts = $query->select('*') ->from('products') ->join('categories', 'id') ->execute() ->getResult(); foreach ($listProducts as $product){ echo $product->id . ' - ' . $product->productname . '($' . $product->price . ') - '. $product->categories->categoryname .' <br />'; } } catch(Exception $e){ echo $e->getMessage(); }
按价格排序获取categoryid=1
且price>200
的products
$query = $service->initializeQueryBuilder(); try{ $listProducts = $query->select('*') ->from('products') ->join('categories', 'id') ->where('categoryid', 'eq.1') //eq -> equal ->where('price', 'gt.200') // gt -> greater than ->order('price.asc') //"price.desc" for descending ->execute() ->getResult(); foreach ($listProducts as $product){ echo $product->id . ' - ' . $product->productname . '($' . $product->price . ') - '. $product->categories->categoryname .' <br />'; } } catch(Exception $e){ echo $e->getMessage(); }
在where
方法中使用的某些运算符可在比较运算符部分中查看。