Alex

有的故事值得一直说下去.
Home » Latest Posts

ThinkPHP 使用 PostgreSQL 需要导入一个 pgsql.sql ,然而在PostgreSQL 12版本以后,pg_attrdef.adsrc 被移除了,因此会报错

将 pgsql.sql 中的

pg_attrdef.adsrc
1
替换为

pg_get_expr(pg_attrdef.adbin, pg_attribute.attrelid)
1
然后重新运行一次SQL即可

附:替换完成后的pgsql.sql内容

CREATE OR REPLACE FUNCTION "public"."table_msg" (a_schema_name varchar, a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS
$body$
DECLARE

v_ret tablestruct;
v_oid oid;
v_sql varchar;
v_rec RECORD;
v_key varchar;

BEGIN

SELECT
pg_class.oid  INTO v_oid
FROM
pg_class
INNER JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid AND lower(pg_namespace.nspname) = a_schema_name)
WHERE
pg_class.relname=a_table_name;
IF NOT FOUND THEN
RETURN;
END IF;
v_sql='
SELECT
pg_attribute.attname AS fields_name,
pg_attribute.attnum AS fields_index,
pgsql_type(pg_type.typname::varchar) AS fields_type,
pg_attribute.atttypmod-4 as fields_length,
CASE WHEN pg_attribute.attnotnull  THEN ''not null''
ELSE ''''
END AS fields_not_null,
pg_get_expr(pg_attrdef.adbin, pg_attribute.attrelid) AS fields_default,
pg_description.description AS fields_comment
FROM
pg_attribute
INNER JOIN pg_class  ON pg_attribute.attrelid = pg_class.oid
INNER JOIN pg_type   ON pg_attribute.atttypid = pg_type.oid
LEFT OUTER JOIN pg_attrdef ON pg_attrdef.adrelid = pg_class.oid AND pg_attrdef.adnum = pg_attribute.attnum
LEFT OUTER JOIN pg_description ON pg_description.objoid = pg_class.oid AND pg_description.objsubid = pg_attribute.attnum
WHERE
pg_attribute.attnum > 0
AND attisdropped <> ''t''
AND pg_class.oid = ' || v_oid || '
ORDER BY pg_attribute.attnum' ;
FOR v_rec IN EXECUTE v_sql LOOP
v_ret.fields_name=v_rec.fields_name;
v_ret.fields_type=v_rec.fields_type;
IF v_rec.fields_length > 0 THEN
v_ret.fields_length:=v_rec.fields_length;
ELSE
v_ret.fields_length:=NULL;
END IF;
v_ret.fields_not_null=v_rec.fields_not_null;
v_ret.fields_default=v_rec.fields_default;
v_ret.fields_comment=v_rec.fields_comment;
SELECT constraint_name INTO v_key FROM information_schema.key_column_usage WHERE table_schema=a_schema_name AND table_name=a_table_name AND column_name=v_rec.fields_name;
IF FOUND THEN
v_ret.fields_key_name=v_key;
ELSE
v_ret.fields_key_name='';
END IF;
RETURN NEXT v_ret;
END LOOP;
RETURN ;

END;
$body$

LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

COMMENT ON FUNCTION "public"."table_msg"(a_schema_name varchar, a_table_name varchar)

IS '获得表信息';

---重载一个函数
CREATE OR REPLACE FUNCTION "public"."table_msg" (a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS
$body$
DECLARE

v_ret tablestruct;

BEGIN

FOR v_ret IN SELECT * FROM table_msg('public',a_table_name) LOOP
RETURN NEXT v_ret;
END LOOP;
RETURN;

END;
$body$

LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

COMMENT ON FUNCTION "public"."table_msg"(a_table_name varchar)

IS '获得表信息';

最近做一个功能,需要动态调用一批指定函数,这些函数还分属不同的类。需要调用的类和方法存在一个二维数组中:

$needDo = array(

{

'className' => 'xxx',

'methodName' => 'xxx'

},

……

);

而且各个method 的参数都为空,根据这个情况于是我想到了call_user_func_array 这个函数。

这个函数可以动态的调用某个类中的某个方法,并且可以传递任意个参数,对于当前这个场景可以说是十分的适合了。

下面具体说说这个函数的用法。

给出的定义是这样的:

call_user_func_array : 调用回调函数,并把一个数组参数作为回调函数的参数。

说明:mixed call_user_func_array ( callable $callback , array $param_arr )

把第一个参数作为回调函数(callback)调用,把参数数组做(param_arr)为回调函数的的参数传入。

返回回调函数的结果。如果出错的话就返回FALSE

比如调用的方法不存在 或者类不存在都会返回 FALSE

使用方式主要有以下两种:

一、类内函数的调用

首先呢,这个函数可以支持回调类内的方法,这个时候该函数的第一个参数就不必是数组了,直接把要调用的类内方法的签名放到第一个参数的位置就可以,第二个参数根据实际情况将之顺序放入到数组中即可。

如:

class a { public function b ($c) {return $c;} call_user_func_array('b', array($e))}

二、调用其他类的方法

这个情况会比较复杂,这个时候呢 该函数的第一个参数的类名可以是一个对象,也可以是一个未经初始化的类。方法呢可以支持静态方法和非静态方法。

1、无需实例化调用类的静态方法

call_user_func_array(array('className', 'staticMethodName'), array('param1'));

2、不实例化调用类的非静态方法

call_user_func_array(array('className', 'methodName'), array('param1'));

这种方式使用需要谨慎一点,因为这样使用的话类是没有实例化的,如果调用的方法中有$this语句,会报错,因为 $this 指向的是当前类的一个实例,没有实例化,$this 就是一个空指针,空指针引用是会fatal 的,所以这个方法的使用需要当心一点。

3、调用实例化后的类的非静态方法

$obj = new ClassName();

call_user_func_array(array($obj, 'methodName'), array('param1'));

该函数的第一个参数如果是对象的话,支持传递对象的指针。

call_user_func_array(array(&$obj, 'methodName'), array('param1'));

拓展:

与该函数特别相似的一个函数是 call_user_func。

该方法的定义如下:

call_user_func(callable $callback, mixed $parameter = ?, mixed $... = ?): mixed

第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。

参数 callback

将被调用的回调函数(callable)。

参数 parameter

0个或以上的参数,被传入回调函数。

注意:

请注意,传入call_user_func()的参数不能为引用传递。

这篇文章主要介绍了php面向对象之反射功能与用法,结合实例形式简单分析了php5面向对象反射的概念及具体用法,需要的朋友可以参考下

本文实例讲述了php面向对象之反射功能与用法。分享给大家供大家参考,具体如下:

个人对反射定义的理解:

首先得说说什么叫反射。对于一个新手来说,反射这个概念常常给人一种似懂非懂的 感觉,不知道该如何下手操作。

反射是指:指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类、方法、属性、参数等的详细信息,同时也包括注释。这种动态获取的信息以及动态调用对象的方法 的功能称为反射API。反射是操纵面向对象范型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用。(注意:php中这种反向操作,实在PHP5之后才完全具备)

下面在此我用实例进行说明:

复制

个人实例返回结果:

复制

以上就是本文的全部内容,希望对大家的学习有所帮助。

PHP开发中,反射和魔术方法是两种常用的技巧。当我们需要自动生成代码或者动态调用某些函数时,反射和魔术方法可以使我们的代码更加灵活和高效。在本文中,我们将探讨如何使用反射和魔术方法来实现代码自动生成和动态调用。

反射是PHP提供的一种强大的工具,它可以帮助我们在程序运行时获取类、方法和属性等信息。通过反射,我们可以动态地获取类或对象的方法、属性和注释等信息,使我们可以在开发过程中更加灵活地应对各种需求。

下面我们来看看如何使用反射来实现代码自动生成。在实际开发中,会经常遇到需要根据某个类生成对象实例的情况。通常情况下,我们需要在代码中手动进行实例化,比如:

但是,当我们的程序包含大量的类时,手动实例化每个类是非常繁琐的。而使用反射,我们可以动态地获取某个类的实例,从而避免手动实例化的繁琐和重复工作。

这里介绍一个代码自动生成工具,在这个工具中,我们需要实现一个类,它具有一个方法generateClass($className),可以根据传入的类名动态地生成并返回该类的一个实例。

我们可以先获取类的反射对象:

然后,我们可以通过反射获取类的属性、方法和注释等信息:

使用这些信息,我们可以动态地构造一个类,代码如下:

通过generateClass方法,我们可以动态地生成一个类,并返回该类的一个实例,这个实例可以在程序中随时使用。

另一个常用的技巧是使用魔术方法实现动态调用。PHP中,魔术方法是一些特殊的方法,它们的名称前缀为两个下划线__,当我们调用一个对象不存在或不可见的属性或方法时,PHP会自动调用对应的魔术方法。通过重载魔术方法,我们可以实现对对象属性和方法的动态调用,从而实现更加灵活和高效的程序。

下面我们来看一个示例,假设我们有一个名为$container的对象容器,它可以保存各种类型的对象,而我们的程序需要动态地从容器中获取某个对象并执行其中的某个方法。

使用普通的方法,我们需要手动检查容器中是否存在该对象,然后再调用对应的方法。而使用魔术方法,我们可以通过__call魔术方法来动态调用容器中的对应方法:

通过重载__call魔术方法,我们可以动态地调用对象中的某个方法,并传递参数,从而实现程序的动态调用。

总结:反射和魔术方法是PHP开发中非常有用的技巧。在实际开发中,我们可以使用反射动态地生成类或对象实例,使用魔术方法实现对对象的动态调用。这些技巧可以使我们的代码更加灵活和高效。同时,需要注意的是,过度使用这些技巧也可能导致代码可读性降低,建议在必要的时候使用。

https://rushb.pro/article/JetBrains-license-server.html

Life is fantastic
🥕 More