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参数有效selectfromjoinwherelimitrange
所有上述方法都返回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:在列中搜索指定的模式(不区分大小写)
其他可用运算符
isincscdslsrnxlnxradjovftsplftsphftswftsnot.eqnot.neqnot.gtnot.gtenot.ltnot.ltenot.likenot.ilikenot.isnot.innot.csnot.cdnot.slnot.srnot.nxlnot.nxrnot.adjnot.ovnot.ftsnot.plftsnot.phftsnot.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方法中使用的某些运算符可在比较运算符部分中查看。