定义全局常量

Posted

技术标签:

【中文标题】定义全局常量【英文标题】:Define global constants 【发布时间】:2016-05-01 10:15:10 【问题描述】:

在 Angular 1.x 中,您可以像这样定义常量:

angular.module('mainApp.config', [])
    .constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/')

Angular(使用 TypeScript)中的等价物是什么?

我只是不想在我的所有服务中一遍又一遍地重复 API 基本 URL。

【问题讨论】:

【参考方案1】:

在阅读了该主题的所有答案以及其他一些答案后,我想提供我这些天正在使用的解决方案。

首先我必须为环境添加一个类。有了这个,我实现了我的属性的数据类型,所以它很容易使用。此外,我可以将默认数据绑定到我的环境,这样我就可以在所有环境之间共享公共数据。有时我们有一些在所有环境中具有相同值的变量(例如站点名称),我们不想每次都更改为所有环境。

// environments\ienvironments.ts

export class IEnvironment implements IEnvironmentParams 
  public production: boolean;
  public basicURL: string = 'https://www.someawesomedomain.com';
  public siteName: string = 'My awesome site';

  constructor(params: IEnvironmentParams) 
    this.production = params.production ?? false;
    this.basicURL = params.basicURL ?? this.basicURL;
    this.siteName = params.siteName ?? this.siteName;
  


export interface IEnvironmentParams 
  production: boolean;
  basicURL?: string;
  siteName?: string;

请注意,我使用 IEnvironmentParams 来简化环境的创建,这样我可以传递对象而不会弄乱构造函数参数并避免参数顺序问题,还可以使用 @987654326 提供所需的默认值功能@运算符。

// environments\environment.prod.ts

import IEnvironment, IEnvironmentParams from "./ienvironment";

const params: IEnvironmentParams = 
    production: true
;

export const environment: IEnvironment = new IEnvironment(params);
// environments\environment.ts

import IEnvironment, IEnvironmentParams from "./ienvironment";

const params: IEnvironmentParams = 
    production: false
;

export const environment: IEnvironment = new IEnvironment(params);

用法示例

import environment from "../environments/environment";


// app-routing.module.ts

const routes: Routes = [
   
    path: '', component: HomeComponent,     
    data: 
        title: `$environment.siteName | Home page title!`,
        description: 'some page description',
    
  
];

检查代码完成情况。

// home.component.ts

@Component(
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
)
export class HomeComponent 

  constructor() 
    console.log(`home component constructor - showing evironment.siteName - $environment.siteName`);
  

你可以在任何你想要的地方使用它,类、服务、指令、组件等。

对于那些想在构建后替换值的人。你能行的。这有点棘手,但是当您构建 Angular 应用程序时,环境数据会导出到 main.js,请看下一个屏幕截图。

只需在任何 IDE 中打开文件并找到 environment 然后替换数据即可。

关于 Angular Universal 项目。构建 Angular Universal 项目时,它将导出 2 个main.js,一个用于服务器,一个用于浏览器,因此您必须同时更改两者。

【讨论】:

【参考方案2】:

我还有另一种定义全局常量的方法。因为如果我们在 ts 文件中定义,如果在生产模式下构建,很难找到常量来改变值。

export class SettingService  

  constructor(private http: HttpClient) 

  

  public getJSON(file): Observable<any> 
      return this.http.get("./assets/configs/" + file + ".json");
  
  public getSetting()
      // use setting here
  

在 app 文件夹中,我添加文件夹 configs/setting.json

setting.json 中的内容


    "baseUrl": "http://localhost:52555"

在应用模块中添加APP_INITIALIZER

   
      provide: APP_INITIALIZER,
      useFactory: (setting: SettingService) => function() return setting.getSetting(),
      deps: [SettingService],
      multi: true
    

通过这种方式,我可以更轻松地更改 json 文件中的值。 我也将这种方式用于不断的错误/警告消息。

【讨论】:

我无法使用这个答案。描述根本不够。有空请说明使用情况。【参考方案3】:

所有解决方案似乎都很复杂。我正在为这种情况寻找最简单的解决方案,我只想使用常量。常数很简单。有什么反对以下解决方案的吗?

app.const.ts

'use strict';

export const dist = '../path/to/dist/';

app.service.ts

import * as AppConst from '../app.const'; 

@Injectable()
export class AppService 

    constructor (
    ) 
        console.log('dist path', AppConst.dist );
    


【讨论】:

好吧,您正在使用服务范围之外的变量,因此您也可以使用窗口全局变量。我们正在尝试做的是让常量进入 Angular4 依赖注入系统,这样我们就可以保持范围干净、可存根或可模拟。【参考方案4】:

angular团队自己提供的配置解决方案,可以找到here。

以下是所有相关代码:

1) app.config.ts

import  OpaqueToken  from "@angular/core";

export let APP_CONFIG = new OpaqueToken("app.config");

export interface IAppConfig 
    apiEndpoint: string;


export const AppConfig: IAppConfig =     
    apiEndpoint: "http://localhost:15422/api/"    
;

2) app.module.ts

import  APP_CONFIG, AppConfig  from './app.config';

@NgModule(
    providers: [
         provide: APP_CONFIG, useValue: AppConfig 
    ]
)

3) your.service.ts

import  APP_CONFIG, IAppConfig  from './app.config';

@Injectable()
export class YourService 

    constructor(@Inject(APP_CONFIG) private config: IAppConfig) 
             // You can use config.apiEndpoint now
       

现在您可以在任何地方注入配置,而无需使用字符串名称并使用您的接口进行静态检查。

您当然可以进一步分离接口和常量,以便能够在生产和开发中提供不同的值,例如

【讨论】:

它只在我没有在服务的构造函数中指定类型时才有效。所以当我做构造函数时它起作用(@Inject(APP_CONFIG) private config)这里提到了这个:blog.thoughtram.io/angular/2016/05/23/… 但不是为什么。 我想你错过了一些 import 或 export 关键字或类似的东西,因为我将它与界面一起使用,正如你所说,让它显式静态输入非常重要。也许您需要在此处提供确切的例外情况。 这些解决方案都不是,即使是 Angular 团队推荐的方法看起来也很优雅。为什么尝试在 Angular 2 中创建常量是一个繁琐的过程?你看不出 Angular1 是如何做到无缝衔接的吗?为什么这么乱? 对于遇到此答案的其他人来说,Angular v4 中的 OpaqueToken 对于 InjectionToken - blog.thoughtram.io/angular/2016/05/23/… “已弃用” 将步骤 1 中的代码放入 environment.tsenvironment.prod.ts 是否有意义,以便您可以在每个环境中使用不同的常量? @IlyaChernomordik 在他回答的最后一段中开始提到这一点。【参考方案5】:

为 Angular 4+ 更新

如果您的项目是通过 angular-cli 生成的,现在我们可以简单地使用 angular 提供默认值的环境文件。

例如

在您的环境文件夹中创建以下文件

environment.prod.ts environment.qa.ts environment.dev.ts

并且每个文件都可以保存相关的代码更改,例如:

environment.prod.ts

export const environment = 
     production: true,
     apiHost: 'https://api.somedomain.com/prod/v1/',
     CONSUMER_KEY: 'someReallyStupidTextWhichWeHumansCantRead', 
     codes: [ 'AB', 'AC', 'XYZ' ],
;

environment.qa.ts

export const environment = 
     production: false,
     apiHost: 'https://api.somedomain.com/qa/v1/',
     CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
     codes: [ 'AB', 'AC', 'XYZ' ],
;

environment.dev.ts

export const environment = 
     production: false,
     apiHost: 'https://api.somedomain.com/dev/v1/',
     CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
     codes: [ 'AB', 'AC', 'XYZ' ],
;

应用中的用例

您可以将环境导入任何文件,例如服务clientUtilServices.ts

import environment from '../../environments/environment';

getHostURL(): string 
    return environment.apiHost;
  

构建中的用例

打开您的 Angular cli 文件 .angular-cli.json 并在 "apps": [...] 中添加以下代码

 "apps":[
        "environments": 
            "dev": "environments/environment.ts",
            "prod": "environments/environment.prod.ts",
            "qa": "environments/environment.qa.ts",
           
         
       ]

如果你想为生产构建,运行 ng build --env=prod 它将从 environment.prod.ts 读取配置,你可以为 qadev 做同样的事情

## 旧答案

我一直在我的提供商中做如下的事情:

import Injectable from '@angular/core';

@Injectable()
export class ConstantService 

API_ENDPOINT :String;
CONSUMER_KEY : String;

constructor() 
    this.API_ENDPOINT = 'https://api.somedomain.com/v1/';
    this.CONSUMER_KEY = 'someReallyStupidTextWhichWeHumansCantRead'
  

然后我可以在任何地方访问所有常量数据

import Injectable from '@angular/core';
import Http from '@angular/http';
import 'rxjs/add/operator/map';

import ConstantService from  './constant-service'; //This is my Constant Service


@Injectable()
export class ImagesService 
    constructor(public http: Http, public ConstantService: ConstantService) 
    console.log('Hello ImagesService Provider');

    

callSomeService() 

    console.log("API_ENDPOINT: ",this.ConstantService.API_ENDPOINT);
    console.log("CONSUMER_KEY: ",this.ConstantService.CONSUMER_KEY);
    var url = this.ConstantService.API_ENDPOINT;
    return this.http.get(url)
  
 

【讨论】:

这不像常量那样工作。常量的值始终相同。在您的情况下,您的 API_ENDPOINT 值可以在任何时间点被覆盖。如果在从constant-service 导入所谓的“常量”之后的任何时候在类中声明this.ConstantService.API_ENDPOINT = 'blah blah',API_ENDPOINT 的新值将是'blah blah'。您的解决方案只是展示了如何使用服务而不是使用常量来访问变量。 @Devner 将它们设为只读 readonly API_ENDPOINT :String; @Anjum 角度如何选择 env 文件。启动应用程序时是否需要传递环境名称? @notionquest 是的,你可以通过它,比如ng build --env=prod 我同意@Devner。常量和环境变量之间有一个非常明显的区别。环境变量相当灵活,可以针对不同的部署实例进行更改。常量,例如路由名称不需要针对不同的实例进行更改。否则,你最终会膨胀 env 文件【参考方案6】:

在 Angular 2 中创建应用程序范围常量的最佳方法是使用 environment.ts 文件。声明此类常量的好处是您可以根据环境改变它们,因为每个环境可以有不同的环境文件。

【讨论】:

如果您打算构建应用程序然后将其部署到多个环境,则此方法不起作用。 @JensBodal:是的,我也有同样的问题。使用环境文件似乎是一个干净的设计,除了你不能使用你的 pre-prod 构建进行生产。此外,它需要在开发环境中进行生产设置,这有时会带来安全问题。【参考方案7】:

Angular4 的一种方法是在模块级别定义一个常量:

const api_endpoint = 'http://127.0.0.1:6666/api/';

@NgModule(
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: [
    MessageService,
    provide: 'API_ENDPOINT', useValue: api_endpoint
  ]
)
export class AppModule 

那么,为您服务:

import Injectable, Inject from '@angular/core';

@Injectable()
export class MessageService 

    constructor(private http: Http, 
      @Inject('API_ENDPOINT') private api_endpoint: string)  

    getMessages(): Observable<Message[]> 
        return this.http.get(this.api_endpoint+'/messages')
            .map(response => response.json())
            .map((messages: Object[]) => 
                return messages.map(message => this.parseData(message));
            );
    

    private parseData(data): Message 
        return new Message(data);
    

【讨论】:

【参考方案8】:

在 Angular 4 中,您可以使用环境类来保留所有全局变量。

默认情况下你有 environment.ts 和 environment.prod.ts。

例如

export const environment = 
  production: false,
  apiUrl: 'http://localhost:8000/api/'
;

然后为您服务:

import  environment  from '../../environments/environment';
...
environment.apiUrl;

【讨论】:

如果您尝试访问服务内部的const,您可能必须在应用模块的providers 数组中“提供”它: provide: 'ConstName', useValue: ConstName 。如果没有这个,我会遇到运行时错误。 @daleyjem 那是因为你试图注入它。这种方法不使用注入器 像这样创建一个常量是最简单的。我猜想失去 DI 从而失去可测试性/mockValue 的反论点有些时候被夸大了。在典型的应用程序中,我们使用了很多非 DI 组件,例如 (RxJS),而不会影响可测试性。【参考方案9】:

这是我最近对这种情况的体验:

@angular/cli: 1.0.0 节点:6.10.2 @angular/core: 4.0.0

我在这里关注了官方和更新的文档:

https://angular.io/docs/ts/latest/guide/dependency-injection.html#!#dependency-injection-tokens

似乎 OpaqueToken 现在已弃用,我们必须使用 InjectionToken,所以这些是我运行的文件,就像一个魅力:

app-config.interface.ts

export interface IAppConfig 

  STORE_KEY: string;


app-config.constants.ts

import  InjectionToken  from "@angular/core";
import  IAppConfig  from "./app-config.interface";

export const APP_DI_CONFIG: IAppConfig = 

  STORE_KEY: 'l@_list@'

;

export let APP_CONFIG = new InjectionToken< IAppConfig >( 'app.config' );

app.module.ts

import  APP_CONFIG, APP_DI_CONFIG  from "./app-config/app-config.constants";

@NgModule( 
  declarations: [ ... ],
  imports: [ ... ],
  providers: [
    ...,
    
      provide: APP_CONFIG,
      useValue: APP_DI_CONFIG
    
  ],
  bootstrap: [ ... ]
 )
export class AppModule 

my-service.service.ts

  constructor( ...,
               @Inject( APP_CONFIG ) private config: IAppConfig) 

    console.log("This is the App's Key: ", this.config.STORE_KEY);
    //> This is the App's Key:  l@_list@

  

结果很干净,控制台上没有警告感谢 John Papa 最近在此问题上的评论:

https://github.com/angular/angular-cli/issues/2034

关键是在不同的文件中实现接口。

【讨论】:

另见***.com/a/43193574/3092596 - 基本相同,但创建可注入模块而不是提供程序【参考方案10】:

AngularJS 的module.constant 没有定义标准意义上的常量。

虽然它作为提供者注册机制独立存在,但最好在相关的 module.value ($provide.value) 函数的上下文中理解。官方文档清楚地说明了用例:

用 $injector 注册一个值服务,例如字符串、数字、数组、对象或函数。这是注册服务的缩写,其中提供者的 $get 属性是一个工厂函数,不接受任何参数并返回值服务。这也意味着不可能将其他服务注入到价值服务中。

将此与module.constant ($provide.constant) 的文档进行比较,后者也清楚地说明了用例(强调我的):

用$injector注册一个常量服务,如字符串、数字、数组、对象或函数。像值一样,不可能将其他服务注入常量。 但与 value 不同的是,常量可以注入到模块配置函数中(参见 angular.Module),并且不能被 AngularJS 装饰器覆盖

因此,AngularJS constant 函数没有提供字段中术语的通常理解含义的常量。

也就是说,对提供的对象施加的限制,以及它通过 $injector 更早的可用性,清楚地表明该名称是通过类比使用的。

如果你想在 AngularJS 应用程序中使用一个实际的常量,你可以像在任何 javascript 程序中一样“提供”一个

export const π = 3.14159265;

在 Angular 2 中,同样的技术也适用。

Angular 2 应用程序没有与 AngularJS 应用程序相同的配置阶段。此外,没有服务装饰器机制 (AngularJS Decorator),但考虑到它们之间的差异,这并不特别令人惊讶。

例子

angular
  .module('mainApp.config', [])
  .constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/');

是含糊的武断和有点令人反感,因为 $provide.constant 被用来指定一个对象,顺便说一下也是一个常量。你还不如写了

export const apiEndpoint = 'http://127.0.0.1:6666/api/';

任何一个都可以改变。

现在关于可测试性的论点,嘲笑常数,被削弱了,因为它实际上并没有改变。

一个人不会嘲笑 π。

当然,您的应用程序特定语义可能是您的端点可能会更改,或者您的 API 可能具有不透明的故障转移机制,因此在某些情况下更改 API 端点是合理的。

但在这种情况下,将其作为单个 URL 的字符串文字表示提供给 constant 函数是行不通的。

一个更好的论点,可能更符合 AngularJS $provide.constant 函数存在的原因是,当 AngularJS 被引入时,JavaScript 没有 标准 模块概念。在这种情况下,全局变量将用于共享可变或不可变的值,并且使用全局变量是有问题的。

也就是说,通过框架提供这样的东西会增加与该框架的耦合。它还将 Angular 特定的逻辑与适用于任何其他系统的逻辑混合在一起。

这并不是说这是一种错误或有害的方法,但就个人而言,如果我想在 Angular 2 应用程序中使用 constant,我会写

export const π = 3.14159265;

就像我使用 AngularJS 一样。

变化越多……

【讨论】:

【参考方案11】:

你可以为你的全局变量创建一个类,然后像这样导出这个类:

export class CONSTANT 
    public static message2 = [
         "NAME_REQUIRED": "Name is required" 
    ]

    public static message = 
        "NAME_REQUIRED": "Name is required",
    

创建并导出CONSTANT 类后,您应该在要使用的类中导入该类,如下所示:

import  Component, OnInit                        from '@angular/core';
import  CONSTANT                                 from '../../constants/dash-constant';


@Component(
  selector   : 'team-component',
  templateUrl: `../app/modules/dashboard/dashComponents/teamComponents/team.component.html`,
)

export class TeamComponent implements OnInit 
  constructor() 
    console.log(CONSTANT.message2[0].NAME_REQUIRED);
    console.log(CONSTANT.message.NAME_REQUIRED);
  

  ngOnInit() 
    console.log("oninit");
    console.log(CONSTANT.message2[0].NAME_REQUIRED);
    console.log(CONSTANT.message.NAME_REQUIRED);
  

您可以在constructorngOnInit() 或任何预定义方法中使用它。

【讨论】:

【参考方案12】:

如果您使用我推荐的Webpack,您可以为不同的环境设置常量。当您在每个环境中具有不同的常量值时,这尤其有价值。

/config 目录下可能有多个 webpack 文件(例如,webpack.dev.js、webpack.prod.js 等)。然后你会有一个custom-typings.d.ts,你会在那里添加它们。以下是每个文件中要遵循的一般模式以及组件中的示例用法。

webpack.env.js

const API_URL = process.env.API_URL = 'http://localhost:3000/';
const JWT_TOKEN_NAME = "id_token";
...
    plugins: [
      // NOTE: when adding more properties, make sure you include them in custom-typings.d.ts
      new DefinePlugin(
        'API_URL': JSON.stringify(API_URL),
        'JWT_TOKEN_NAME': JSON.stringify(JWT_TOKEN_NAME)
      ),

custom-typings.d.ts

declare var API_URL: string;
declare var JWT_TOKEN_NAME: string;
interface GlobalEnvironment 
  API_URL: string;
  JWT_TOKEN_NAME: string;

组件

export class HomeComponent implements OnInit 
  api_url:string = API_URL;
  authToken: string = "Bearer " + localStorage.getItem(JWT_TOKEN_NAME));

【讨论】:

【参考方案13】:

以下更改适用于 Angular 2 最终版本:

export class AppSettings 
   public static API_ENDPOINT='http://127.0.0.1:6666/api/';

然后在服务中:

import Http from 'angular2/http';
import Message from '../models/message';
import Injectable from 'angular2/core';
import Observable from 'rxjs/Observable';
import AppSettings from '../appSettings';
import 'rxjs/add/operator/map';

@Injectable()
export class MessageService 

    constructor(private http: Http)  

    getMessages(): Observable<Message[]> 
        return this.http.get(AppSettings.API_ENDPOINT+'/messages')
            .map(response => response.json())
            .map((messages: Object[]) => 
                return messages.map(message => this.parseData(message));
            );
    

    private parseData(data): Message 
        return new Message(data);
    

【讨论】:

我认为 AppSettings 类应该是抽象的,API_ENDPOINT 成员应该是 readonly【参考方案14】:

在 Angular2 中,您有以下 provide 定义,它允许您设置不同类型的依赖项:

provide(token: any, useClass, useValue, useExisting, useFactory, deps, multi

与 Angular 1 相比

Angular1 中的app.service 等价于Angular2 中的useClass

Angular1 中的app.factory 等价于Angular2 中的useFactory

app.constantapp.value 已简化为 useValue,约束更少。即不再有 config 块。

app.provider - Angular 2 中没有等价物。

示例

使用根注入器进行设置:

bootstrap(AppComponent,[provide(API_ENDPOINT,  useValue='http://127.0.0.1:6666/api/' )]);

或使用组件的注入器进行设置:

providers: [provide(API_ENDPOINT,  useValue: 'http://127.0.0.1:6666/api/')]

provide 是:

var injectorValue = Injector.resolveAndCreate([
  new Provider(API_ENDPOINT,  useValue: 'http://127.0.0.1:6666/api/')
]);

使用注入器,获取值很容易:

var endpoint = injectorValue.get(API_ENDPOINT);

【讨论】:

我实际上想将我的设置放在一个外部文件中,例如:settings.ts 这个文件是什么样子的? 您是否考虑过 NodeJS 等服务器端 javascript? 抱歉,我不明白如何将它注入到我的服务中?由于我使用的是外部文件,我需要将其导出吗? 我会让它成为您构建配置过程的一部分。即根据您的环境,将不同的文件编译/打包在一起,然后部署。所有这些你都可以用 NodeJS 和适当的模块来完成。 NodeJS 不是一个选项,不幸的是。【参考方案15】:

使用在构建过程中生成的属性文件既简单又容易。这是 Angular CLI 使用的方法。为每个环境定义一个属性文件,并在构建期间使用命令来确定将哪个文件复制到您的应用程序。然后只需导入要使用的属性文件。

https://github.com/angular/angular-cli#build-targets-and-environment-files

【讨论】:

【参考方案16】:

虽然使用带有字符串常量的 AppSettings 类作为 ApiEndpoint 的方法有效,但它并不理想,因为我们无法在单元测试时将这个真实的 ApiEndpoint 交换为其他一些值。

我们需要能够将这个 api 端点注入到我们的服务中(想想将一个服务注入到另一个服务中)。我们也不需要为此创建一个完整的类,我们要做的就是将一个字符串注入到我们的服务中,作为我们的 ApiEndpoint。要完成excellent answer by pixelbits,这里是关于如何在 Angular 2 中完成的完整代码:

首先,我们需要告诉 Angular 在我们的应用中请求时如何提供我们的 ApiEndpoint 实例(将其视为注册依赖项):

bootstrap(AppComponent, [
        HTTP_PROVIDERS,
        provide('ApiEndpoint', useValue: 'http://127.0.0.1:6666/api/')
]);         

然后在服务中,我们将这个 ApiEndpoint注入到服务构造函数中,Angular 将根据我们上面的注册为我们提供它:

import Http from 'angular2/http';
import Message from '../models/message';
import Injectable, Inject from 'angular2/core';  // * We import Inject here
import Observable from 'rxjs/Observable';
import AppSettings from '../appSettings';
import 'rxjs/add/operator/map';

@Injectable()
export class MessageService 

    constructor(private http: Http, 
                @Inject('ApiEndpoint') private apiEndpoint: string)  

    getMessages(): Observable<Message[]> 
        return this.http.get(`$this.apiEndpoint/messages`)
            .map(response => response.json())
            .map((messages: Object[]) => 
                return messages.map(message => this.parseData(message));
            );
     
    // the rest of the code...

【讨论】:

现在 Angular 团队在他们的教程中推荐了一种“官方”方式。我在下面添加了一个答案:(***.com/a/40287063/1671558) 这段代码已经不准确了,实现这个会导致在AppComponent上找不到ApiEndpoint。 好的,我并不孤单。你知道这个破的是哪个版本吗?是否有另一种方法不需要在全局对象上定义值然后提供它们?【参考方案17】:

只需使用 Typescript 常量

export var API_ENDPOINT = 'http://127.0.0.1:6666/api/';

你可以在依赖注入器中使用它

bootstrap(AppComponent, [provide(API_ENDPOINT, useValue: 'http://127.0.0.1:6666/api/'), ...]);

【讨论】:

为什么要注入它?我认为不需要...您一导入就可以使用它。 @SnareChops @Sasxa 我同意,尽管它可能对单元测试等有好处。只是想提供一个完整的答案。 @Andreas 你可以使用constyest 请提供此工作的堆栈闪电。我见过很多在引导方法中提供服务的例子,但还没有找到一个足够有效的例子。可能在更新版本的 Angular 中发生了一些变化。

以上是关于定义全局常量的主要内容,如果未能解决你的问题,请参考以下文章

Extjs如何定义一个全局常量文件

php 类中定义全局变量|php类定义变量|php类定义常量

thinkphp 5.0 怎么设置模版的全局变量【常量也行】

如何避免全局常量的“多重定义”错误?

在 C++ 中创建全局“常量”的正确方法

PHP 常量PHP 变量全解析(超全局变量变量的8种数据类型等)